Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature/OFFICIALLY UNSUPPORTED] add nowasm build tag to disable building with WebAssembly #3429

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/db/sqlite/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build !moderncsqlite3
//go:build !moderncsqlite3 && !nowasm

package sqlite

Expand Down
2 changes: 1 addition & 1 deletion internal/db/sqlite/driver_moderncsqlite3.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build moderncsqlite3
//go:build moderncsqlite3 || nowasm

package sqlite

Expand Down
2 changes: 1 addition & 1 deletion internal/db/sqlite/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build !moderncsqlite3
//go:build !moderncsqlite3 && !nowasm

package sqlite

Expand Down
2 changes: 1 addition & 1 deletion internal/db/sqlite/errors_moderncsqlite3.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build moderncsqlite3
//go:build moderncsqlite3 || nowasm

package sqlite

Expand Down
28 changes: 28 additions & 0 deletions internal/media/ffmpeg/args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package ffmpeg

import (
"codeberg.org/gruf/go-ffmpreg/wasm"
)

// Args encapsulates the passing of common
// configuration options to run an instance
// of a compiled WebAssembly module that is
// run in a typical CLI manner.
type Args = wasm.Args
142 changes: 142 additions & 0 deletions internal/media/ffmpeg/exec_nowasm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build nowasm

package ffmpeg

import (
"context"
"fmt"
"io"
"io/fs"
"os/exec"

"codeberg.org/gruf/go-ffmpreg/wasm"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/sys"
)

func init() {
fmt.Println("!! you are using an unsupported build configuration of gotosocial with WebAssembly disabled !!")
fmt.Println("!! please do not file bug reports regarding media processing with this configuration !!")
fmt.Println("!! it is also less secure; this does not enforce version checks on ffmpeg / ffprobe versions !!")
tsmethurst marked this conversation as resolved.
Show resolved Hide resolved
}

// runCmd will run 'name' with the given arguments, returning exit code or error.
func runCmd(ctx context.Context, name string, args wasm.Args) (uint32, error) {
cmd := exec.CommandContext(ctx, name, args.Args...) //nolint:gosec

// Set provided std files.
cmd.Stdin = args.Stdin
cmd.Stdout = args.Stdout
cmd.Stderr = args.Stderr

if args.Config != nil {
// Gather some information
// from module config func.
var cfg falseModuleConfig
_ = args.Config(&cfg)

// Extract from conf.
cmd.Env = cfg.env
}

// Run prepared command, catching err type.
switch err := cmd.Run(); err := err.(type) {

// Extract code from
// any exit error type.
case *exec.ExitError:
rc := err.ExitCode()
return uint32(rc), err

default:
return 0, err
}
}

type falseModuleConfig struct{ env []string }

func (cfg *falseModuleConfig) WithArgs(...string) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithEnv(key string, value string) wazero.ModuleConfig {
cfg.env = append(cfg.env, key+"="+value)
return cfg // noop
}

func (cfg *falseModuleConfig) WithFS(fs.FS) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithFSConfig(wazero.FSConfig) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithName(string) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithStartFunctions(...string) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithStderr(io.Writer) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithStdin(io.Reader) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithStdout(io.Writer) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithWalltime(sys.Walltime, sys.ClockResolution) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithSysWalltime() wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithNanotime(sys.Nanotime, sys.ClockResolution) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithSysNanotime() wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithNanosleep(sys.Nanosleep) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithOsyield(sys.Osyield) wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithSysNanosleep() wazero.ModuleConfig {
return cfg // noop
}

func (cfg *falseModuleConfig) WithRandSource(io.Reader) wazero.ModuleConfig {
return cfg // noop
}
8 changes: 7 additions & 1 deletion internal/media/ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build !nowasm

package ffmpeg

import (
"context"

"codeberg.org/gruf/go-ffmpreg/wasm"
)

// ffmpegRunner limits the number of
Expand All @@ -36,5 +40,7 @@ func InitFfmpeg(ctx context.Context, max int) error {

// Ffmpeg runs the given arguments with an instance of ffmpeg.
func Ffmpeg(ctx context.Context, args Args) (uint32, error) {
return ffmpegRunner.Run(ctx, ffmpeg, args)
return ffmpegRunner.Run(ctx, func() (uint32, error) {
return wasm.Run(ctx, runtime, ffmpeg, args)
})
}
49 changes: 49 additions & 0 deletions internal/media/ffmpeg/ffmpeg_nowasm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build nowasm

package ffmpeg

import (
"context"
"os/exec"
)

// ffmpegRunner limits the number of
// ffmpeg WebAssembly instances that
// may be concurrently running, in
// order to reduce memory usage.
var ffmpegRunner runner

// InitFfmpeg looks for a local copy of ffmpeg in path, and prepares
// the runner to only allow max given concurrent running instances.
func InitFfmpeg(ctx context.Context, max int) error {
_, err := exec.LookPath("ffmpeg")
if err != nil {
return err
}
ffmpegRunner.Init(max)
return nil
}

// Ffmpeg runs the given arguments with an instance of ffmpeg.
func Ffmpeg(ctx context.Context, args Args) (uint32, error) {
return ffmpegRunner.Run(ctx, func() (uint32, error) {
return runCmd(ctx, "ffmpeg", args)
})
}
8 changes: 7 additions & 1 deletion internal/media/ffmpeg/ffprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build !nowasm

package ffmpeg

import (
"context"

"codeberg.org/gruf/go-ffmpreg/wasm"
)

// ffprobeRunner limits the number of
Expand All @@ -36,5 +40,7 @@ func InitFfprobe(ctx context.Context, max int) error {

// Ffprobe runs the given arguments with an instance of ffprobe.
func Ffprobe(ctx context.Context, args Args) (uint32, error) {
return ffprobeRunner.Run(ctx, ffprobe, args)
return ffmpegRunner.Run(ctx, func() (uint32, error) {
return wasm.Run(ctx, runtime, ffprobe, args)
})
}
49 changes: 49 additions & 0 deletions internal/media/ffmpeg/ffprobe_nowasm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

//go:build nowasm

package ffmpeg

import (
"context"
"os/exec"
)

// ffprobeRunner limits the number of
// ffprobe WebAssembly instances that
// may be concurrently running, in
// order to reduce memory usage.
var ffprobeRunner runner

// InitFfprobe looks for a local copy of ffprobe in path, and prepares
// the runner to only allow max given concurrent running instances.
func InitFfprobe(ctx context.Context, max int) error {
_, err := exec.LookPath("ffprobe")
if err != nil {
return err
}
ffprobeRunner.Init(max)
return nil
}

// Ffprobe runs the given arguments with an instance of ffprobe.
func Ffprobe(ctx context.Context, args Args) (uint32, error) {
return ffprobeRunner.Run(ctx, func() (uint32, error) {
return runCmd(ctx, "ffprobe", args)
})
}
9 changes: 3 additions & 6 deletions internal/media/ffmpeg/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ package ffmpeg

import (
"context"

"codeberg.org/gruf/go-ffmpreg/wasm"
"github.com/tetratelabs/wazero"
)

// runner simply abstracts away the complexities
Expand Down Expand Up @@ -53,7 +50,7 @@ func (r *runner) Init(n int) {

// Run will attempt to pass the given compiled WebAssembly module with args to run(), waiting on
// the receiving runner until a free slot is available to run an instance, (if a limit is enabled).
func (r *runner) Run(ctx context.Context, cmod wazero.CompiledModule, args Args) (uint32, error) {
func (r *runner) Run(ctx context.Context, run func() (uint32, error)) (uint32, error) {
select {
// Context canceled.
case <-ctx.Done():
Expand All @@ -66,6 +63,6 @@ func (r *runner) Run(ctx context.Context, cmod wazero.CompiledModule, args Args)
// Release slot back to pool on end.
defer func() { r.pool <- struct{}{} }()

// Pass to main module runner function.
return wasm.Run(ctx, runtime, cmod, args)
// Call run.
return run()
}
Loading