From 7bca38badbfba178c33b4c3d8a5a4d6b919f86de Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Mon, 13 Oct 2025 13:06:47 +0200 Subject: [PATCH] add self-upgrader (#3501) (#5035) this allows to upgrade MediaMTX to latest version by running ./mediamtx --upgrade --- .github/workflows/release.yml | 4 +- README.md | 2 +- .../{2-installation.md => 2-install.md} | 22 +- docs/1-kickoff/3-upgrade.md | 36 ++++ docs/4-other/3-security.md | 24 ++- go.mod | 3 + go.sum | 12 ++ internal/core/core.go | 12 +- internal/core/upgrade.go | 195 ++++++++++++++++++ internal/core/upgrade_disabled.go | 9 + scripts/binaries.mk | 14 +- scripts/dockerhub.mk | 4 + 12 files changed, 311 insertions(+), 26 deletions(-) rename docs/1-kickoff/{2-installation.md => 2-install.md} (68%) create mode 100644 docs/1-kickoff/3-upgrade.md create mode 100644 internal/core/upgrade.go create mode 100644 internal/core/upgrade_disabled.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fadd5365..accca302 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,13 +65,13 @@ jobs: + `Binaries are compiled from source through the [Release workflow](https://github.com/${owner}/${repo}/actions/workflows/release.yml) without human intervention,` + ` preventing any external interference.\n` + `\n` - + 'You can verify that binaries have been produced by the workflow by using [GitHub Attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds):\n' + + 'You can verify that binaries have been produced by the workflow by using [GitHub Attestations](https://docs.github.com/en/actions/concepts/security/artifact-attestations):\n' + `\n` + '```\n' + `ls mediamtx_* | xargs -L1 gh attestation verify --repo bluenviron/mediamtx\n` + '```\n' + `\n` - + 'You can verify the binaries checksum by downloading `checksums.sha256` and running:\n' + + 'You can verify checksums of binaries by downloading `checksums.sha256` and running:\n' + `\n` + '```\n' + `cat checksums.sha256 | grep "$(ls mediamtx_*)" | sha256sum --check\n` diff --git a/README.md b/README.md index dcbc0695..e7ae3141 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ _MediaMTX_ is a ready-to-use and zero-dependency real-time media server and medi
- |[Installation](https://mediamtx.org/docs/kickoff/installation)|[Documentation](https://mediamtx.org/docs/kickoff/introduction)| + |[Install](https://mediamtx.org/docs/kickoff/install)|[Documentation](https://mediamtx.org/docs/kickoff/introduction)| |-|-|
diff --git a/docs/1-kickoff/2-installation.md b/docs/1-kickoff/2-install.md similarity index 68% rename from docs/1-kickoff/2-installation.md rename to docs/1-kickoff/2-install.md index 02a8dffa..66329ff8 100644 --- a/docs/1-kickoff/2-installation.md +++ b/docs/1-kickoff/2-install.md @@ -1,4 +1,4 @@ -# Installation +# Install There are several installation methods available: standalone binary, Docker image, Arch Linux package, FreeBSD Ports Collection or package and OpenWrt binary. @@ -17,17 +17,21 @@ There are several installation methods available: standalone binary, Docker imag Download and launch the image: ```sh -docker run --rm -it --network=host bluenviron/mediamtx:latest +docker run --rm -it --network=host bluenviron/mediamtx:1 ``` -Available images: +The `1` tag corresponds to the latest `v1.x.x` release, that should guarantee backward compatibility when upgrading. -| name | FFmpeg included | RPI Camera support | -| ------------------------------------- | ------------------ | ------------------ | -| bluenviron/mediamtx:latest | :x: | :x: | -| bluenviron/mediamtx:latest-ffmpeg | :heavy_check_mark: | :x: | -| bluenviron/mediamtx:latest-rpi | :x: | :heavy_check_mark: | -| bluenviron/mediamtx:latest-ffmpeg-rpi | :heavy_check_mark: | :heavy_check_mark: | +It is also possible to bind the image to a specific release, by using the release name as tag (`bluenviron/mediamtx:{docker_version_tag}`). + +There are four image variants: + +| name | FFmpeg included | RPI Camera support | +| -------------------------------- | ------------------ | ------------------ | +| bluenviron/mediamtx:1 | :x: | :x: | +| bluenviron/mediamtx:1-ffmpeg | :heavy_check_mark: | :x: | +| bluenviron/mediamtx:1-rpi | :x: | :heavy_check_mark: | +| bluenviron/mediamtx:1-ffmpeg-rpi | :heavy_check_mark: | :heavy_check_mark: | The `--network=host` flag is mandatory for RTSP to work, since Docker can change the source port of UDP packets for routing reasons, and this doesn't allow the server to identify the senders of the packets. diff --git a/docs/1-kickoff/3-upgrade.md b/docs/1-kickoff/3-upgrade.md new file mode 100644 index 00000000..130756a8 --- /dev/null +++ b/docs/1-kickoff/3-upgrade.md @@ -0,0 +1,36 @@ +# Upgrade + +If you have an existing MediaMTX installation and want to upgrade it to the latest version, the procedure depends on how MediaMTX was installed. + +## Standalone binary + +The standalone binary comes with a upgrade utility that can be launched with: + +```sh +./mediamtx --upgrade +``` + +This will replace the MediaMTX executable with its latest version. Privileges to write to the executable location are required. + +## Docker image + +If you used the `1` tag or the `latest` tag, remove the image from cache and re-download it: + +```sh +docker rm bluenviron/mediamtx:1 +docker restart id-of-mediamtx-container +``` + +## Arch Linux package + +Repeat the installation procedure. + +## FreeBSD + +Repeat the installation procedure. + +## OpenWrt binary + +If the architecture of the OpenWrt device is amd64, armv6, armv7 or arm64, you can use the standalone binary method. + +Otherwise, recompile the server from source. diff --git a/docs/4-other/3-security.md b/docs/4-other/3-security.md index 861017db..443565a8 100644 --- a/docs/4-other/3-security.md +++ b/docs/4-other/3-security.md @@ -1,21 +1,33 @@ # Security -## Reporting vulnerabilities +## Security of released binaries -Vulnerabilities can be reported privately by using the [Security Advisory](https://github.com/bluenviron/mediamtx/security/advisories/new) feature of GitHub. +Binaries published in the [Releases](https://github.com/bluenviron/mediamtx/releases) section of GitHub are the output of a process which has been designed with a security-first approach. Every step from source code to the intended final destination of binaries is fully visible, immune from external interference and can be independently verified. -## Binaries +This is the process: -Binaries are compiled from source through the [Release workflow](https://github.com/bluenviron/mediamtx/actions/workflows/release.yml) without human intervention, preventing any external interference. +1. During every release, the [Release workflow](https://github.com/bluenviron/mediamtx/actions/workflows/release.yml) is triggered on GitHub. -You can verify that binaries have been produced by the workflow by using [GitHub Attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds): +2. The release workflow pulls the source code and builds binaries. + +3. The release workflow computes SHA256 checksums of binaries and publishes them on the Sigstore Public Good Instance through [GitHub Attestations](https://docs.github.com/en/actions/concepts/security/artifact-attestations). + +4. Checksums and binaries are published on the Release page. + +5. Binaries are downloaded by users to the intended final destination. + +It is possible to verify that SHA256 checksums of binaries correspond to the one published on Sigstore by running: ```sh ls mediamtx_* | xargs -L1 gh attestation verify --repo bluenviron/mediamtx ``` -You can verify the binaries checksum by downloading `checksums.sha256` and running: +It is possible to verify that binaries have not been altered during transfer from GitHub to the final destination by downloading `checksums.sha256` and running: ```sh cat checksums.sha256 | grep "$(ls mediamtx_*)" | sha256sum --check ``` + +## Reporting vulnerabilities + +Vulnerabilities can be reported privately by using the [Security Advisory](https://github.com/bluenviron/mediamtx/security/advisories/new) feature of GitHub. diff --git a/go.mod b/go.mod index 15992a3b..8514ea3c 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.25.0 require ( code.cloudfoundry.org/bytefmt v0.54.0 + github.com/Masterminds/semver/v3 v3.4.0 github.com/MicahParks/jwkset v0.11.0 github.com/MicahParks/keyfunc/v3 v3.6.2 github.com/abema/go-mp4 v1.4.1 @@ -25,6 +26,7 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/matthewhartstonge/argon2 v1.4.0 + github.com/minio/selfupdate v0.6.0 github.com/pion/ice/v4 v4.0.10 github.com/pion/interceptor v0.1.41 github.com/pion/logging v0.2.4 @@ -40,6 +42,7 @@ require ( ) require ( + aead.dev/minisign v0.2.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect diff --git a/go.sum b/go.sum index ebf200dd..5740c216 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk= +aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ= code.cloudfoundry.org/bytefmt v0.54.0 h1:xMSFK/+X7MPRmwRExB7wrMvZZOzHoGK2/y9TUx01P14= code.cloudfoundry.org/bytefmt v0.54.0/go.mod h1:uW5EGeU/vy+HOUwUnI38Lz2QK0eHQ+ua31nLOAdatzQ= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= @@ -139,6 +141,8 @@ github.com/matthewhartstonge/argon2 v1.4.0 h1:/nBFmqLd5SG0itPEvASchx3dwLXCHxEeVy github.com/matthewhartstonge/argon2 v1.4.0/go.mod h1:Z0HuEBPD4vGtn881oo/LVTRx7RMzyc1BYSHNBVmS65o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU= +github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -233,6 +237,9 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= @@ -240,25 +247,30 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= diff --git a/internal/core/core.go b/internal/core/core.go index 01733601..85f558fd 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -55,8 +55,9 @@ var defaultConfPathsNotWin = []string{ } var cli struct { - Version bool `help:"print version"` Confpath string `arg:"" default:""` + Version bool `help:"print version"` + Upgrade bool `help:"upgrade executable to the latest version"` } func atLeastOneRecordDeleteAfter(pathConfs map[string]*conf.Path) bool { @@ -137,6 +138,15 @@ func New(args []string) (*Core, bool) { os.Exit(0) } + if cli.Upgrade { + err = upgrade() + if err != nil { + fmt.Printf("ERR: %v\n", err) + os.Exit(1) + } + os.Exit(0) + } + ctx, ctxCancel := context.WithCancel(context.Background()) p := &Core{ diff --git a/internal/core/upgrade.go b/internal/core/upgrade.go new file mode 100644 index 00000000..d1ce7d65 --- /dev/null +++ b/internal/core/upgrade.go @@ -0,0 +1,195 @@ +//go:build enableUpgrade + +package core + +import ( + "archive/tar" + "archive/zip" + "bytes" + "compress/gzip" + "fmt" + "io" + "net/http" + "regexp" + "runtime" + "runtime/debug" + "sort" + + "github.com/Masterminds/semver/v3" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/storage/memory" + "github.com/minio/selfupdate" +) + +const ( + gitRepo = "https://github.com/bluenviron/mediamtx" + downloadURL = "https://github.com/bluenviron/mediamtx/releases/download/%s/mediamtx_%s_%s_%s.%s" + executable = "mediamtx" +) + +var ( + tagsRegexp = regexp.MustCompile(`^refs/tags/(v1\.[0-9]+\.[0-9]+)$`) + currentRegexp = regexp.MustCompile(`^(v1\.[0-9]+\.[0-9]+)$`) +) + +func latestRemoteVersion() (*semver.Version, error) { + rem := git.NewRemote(memory.NewStorage(), &config.RemoteConfig{ + URLs: []string{gitRepo}, + }) + + refs, err := rem.List(&git.ListOptions{}) + if err != nil { + return nil, err + } + + var versions []*semver.Version + + for _, ref := range refs { + matches := tagsRegexp.FindStringSubmatch(ref.Name().String()) + if matches != nil { + v, _ := semver.NewVersion(matches[1]) + versions = append(versions, v) + } + } + + if len(versions) == 0 { + return nil, fmt.Errorf("no versions found") + } + + sort.Sort(sort.Reverse(semver.Collection(versions))) + + return versions[0], nil +} + +func goArm() string { + bi, _ := debug.ReadBuildInfo() + for _, bs := range bi.Settings { + if bs.Key == "GOARM" { + return bs.Value + } + } + return "" +} + +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)) + } + + fmt.Println("getting latest version...") + + latest, err := latestRemoteVersion() + if err != nil { + return err + } + + current, _ := semver.NewVersion(string(version)) + + if current.GreaterThanEqual(latest) { + fmt.Printf("current version (%v) is up to date\n", "v"+current.String()) + return nil + } + + fmt.Printf("downloading version %v...\n", "v"+latest.String()) + + var arch string + if runtime.GOARCH == "arm" { + arch = "armv" + goArm() + } else { + arch = runtime.GOARCH + } + + 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, arch, extension) + + res, err := http.Get(ur) + if err != nil { + return err + } + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + 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) + } + + err = selfupdate.Apply(bytes.NewReader(exe), selfupdate.Options{}) + if err != nil { + return err + } + + fmt.Printf("MediaMTX upgraded successfully from %v to %v.\n", "v"+current.String(), "v"+latest.String()) + return nil +} diff --git a/internal/core/upgrade_disabled.go b/internal/core/upgrade_disabled.go new file mode 100644 index 00000000..ad75b168 --- /dev/null +++ b/internal/core/upgrade_disabled.go @@ -0,0 +1,9 @@ +//go:build !enableUpgrade + +package core + +import "fmt" + +func upgrade() error { + return fmt.Errorf("upgrade command is not available") +} diff --git a/scripts/binaries.mk b/scripts/binaries.mk index 7c0f8699..3f9f8d5c 100644 --- a/scripts/binaries.mk +++ b/scripts/binaries.mk @@ -15,37 +15,37 @@ RUN go generate ./... FROM build-base AS build-windows-amd64 ENV GOOS=windows GOARCH=amd64 -RUN go build -o "tmp/$(BINARY_NAME).exe" +RUN go build -tags enableUpgrade -o "tmp/$(BINARY_NAME).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 ENV GOOS=linux GOARCH=amd64 -RUN go build -o "tmp/$(BINARY_NAME)" +RUN go build -tags enableUpgrade -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 ENV GOOS=darwin GOARCH=amd64 -RUN go build -o "tmp/$(BINARY_NAME)" +RUN go build -tags enableUpgrade -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 ENV GOOS=darwin GOARCH=arm64 -RUN go build -o "tmp/$(BINARY_NAME)" +RUN go build -tags enableUpgrade -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 ENV GOOS=linux GOARCH=arm GOARM=6 -RUN go build -o "tmp/$(BINARY_NAME)" +RUN go build -tags enableUpgrade -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 ENV GOOS=linux GOARCH=arm GOARM=7 -RUN go build -o "tmp/$(BINARY_NAME)" +RUN go build -tags enableUpgrade -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 ENV GOOS=linux GOARCH=arm64 -RUN go build -o "tmp/$(BINARY_NAME)" +RUN go build -tags enableUpgrade -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) diff --git a/scripts/dockerhub.mk b/scripts/dockerhub.mk index a1ed3ab5..307186ce 100644 --- a/scripts/dockerhub.mk +++ b/scripts/dockerhub.mk @@ -12,6 +12,7 @@ dockerhub: -f docker/ffmpeg-rpi.Dockerfile . \ --platform=linux/arm/v6,linux/arm/v7,linux/arm64 \ -t $(DOCKER_REPOSITORY):$(VERSION)-ffmpeg-rpi \ + -t $(DOCKER_REPOSITORY):1-ffmpeg-rpi \ -t $(DOCKER_REPOSITORY):latest-ffmpeg-rpi \ --push @@ -19,6 +20,7 @@ dockerhub: -f docker/rpi.Dockerfile . \ --platform=linux/arm/v6,linux/arm/v7,linux/arm64 \ -t $(DOCKER_REPOSITORY):$(VERSION)-rpi \ + -t $(DOCKER_REPOSITORY):1-rpi \ -t $(DOCKER_REPOSITORY):latest-rpi \ --push @@ -26,6 +28,7 @@ dockerhub: -f docker/ffmpeg.Dockerfile . \ --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 \ -t $(DOCKER_REPOSITORY):$(VERSION)-ffmpeg \ + -t $(DOCKER_REPOSITORY):1-ffmpeg \ -t $(DOCKER_REPOSITORY):latest-ffmpeg \ --push @@ -33,6 +36,7 @@ dockerhub: -f docker/standard.Dockerfile . \ --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64 \ -t $(DOCKER_REPOSITORY):$(VERSION) \ + -t $(DOCKER_REPOSITORY):1 \ -t $(DOCKER_REPOSITORY):latest \ --push