From 7f30b00a1db5c434136d3afc7c336adea694d2c7 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Tue, 29 Oct 2024 15:24:46 +0800 Subject: [PATCH 1/2] feat(functions): allow custom functions entrypoint path --- internal/functions/deploy/bundle.go | 6 +++--- internal/functions/deploy/deploy.go | 4 ++++ internal/functions/serve/templates/main.ts | 1 + pkg/config/config.go | 4 ++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/internal/functions/deploy/bundle.go b/internal/functions/deploy/bundle.go index 0b178b0f7..0119a559c 100644 --- a/internal/functions/deploy/bundle.go +++ b/internal/functions/deploy/bundle.go @@ -44,8 +44,7 @@ func (b *dockerBundler) Bundle(ctx context.Context, entrypoint string, importMap } }() // Create bind mounts - hostEntrypointDir := filepath.Dir(entrypoint) - binds, err := GetBindMounts(cwd, utils.FunctionsDir, hostOutputDir, hostEntrypointDir, importMap, b.fsys) + binds, err := GetBindMounts(cwd, utils.FunctionsDir, hostOutputDir, entrypoint, importMap, b.fsys) if err != nil { return err } @@ -86,7 +85,7 @@ func (b *dockerBundler) Bundle(ctx context.Context, entrypoint string, importMap return function.Compress(eszipBytes, output) } -func GetBindMounts(cwd, hostFuncDir, hostOutputDir, hostEntrypointDir, hostImportMapPath string, fsys afero.Fs) ([]string, error) { +func GetBindMounts(cwd, hostFuncDir, hostOutputDir, hostEntrypointPath, hostImportMapPath string, fsys afero.Fs) ([]string, error) { sep := string(filepath.Separator) // Docker requires all host paths to be absolute if !filepath.IsAbs(hostFuncDir) { @@ -116,6 +115,7 @@ func GetBindMounts(cwd, hostFuncDir, hostOutputDir, hostEntrypointDir, hostImpor } } // Allow entrypoints outside the functions directory + hostEntrypointDir := filepath.Dir(hostEntrypointPath) if len(hostEntrypointDir) > 0 { if !filepath.IsAbs(hostEntrypointDir) { hostEntrypointDir = filepath.Join(cwd, hostEntrypointDir) diff --git a/internal/functions/deploy/deploy.go b/internal/functions/deploy/deploy.go index b18565d20..855d44537 100644 --- a/internal/functions/deploy/deploy.go +++ b/internal/functions/deploy/deploy.go @@ -58,6 +58,10 @@ func GetFunctionSlugs(fsys afero.Fs) (slugs []string, err error) { slugs = append(slugs, slug) } } + // Add all function slugs declared in config file + for slug := range utils.Config.Functions { + slugs = append(slugs, slug) + } return slugs, nil } diff --git a/internal/functions/serve/templates/main.ts b/internal/functions/serve/templates/main.ts index c96847e3e..01afbfeb0 100644 --- a/internal/functions/serve/templates/main.ts +++ b/internal/functions/serve/templates/main.ts @@ -43,6 +43,7 @@ const DENO_SB_ERROR_MAP = new Map([ ]); interface FunctionConfig { + entrypointPath: string; importMapPath: string; verifyJWT: boolean; } diff --git a/pkg/config/config.go b/pkg/config/config.go index 7fc8942b5..a0d9cd29c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -368,10 +368,10 @@ type ( FunctionConfig map[string]function function struct { - Enabled *bool `toml:"enabled"` + Enabled *bool `toml:"enabled" json:"-"` VerifyJWT *bool `toml:"verify_jwt" json:"verifyJWT"` ImportMap string `toml:"import_map" json:"importMapPath,omitempty"` - Entrypoint string `json:"-"` + Entrypoint string `toml:"entrypoint" json:"entrypointPath,omitempty"` } analytics struct { From 82a1cfcc593893431ad39c36f58e428b0a617c27 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Tue, 29 Oct 2024 19:18:09 +0800 Subject: [PATCH 2/2] fix: convert entrypoint path to file url --- internal/functions/serve/serve.go | 10 ++++------ internal/functions/serve/templates/main.ts | 10 +++++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/internal/functions/serve/serve.go b/internal/functions/serve/serve.go index 15320171d..62811d769 100644 --- a/internal/functions/serve/serve.go +++ b/internal/functions/serve/serve.go @@ -109,11 +109,6 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, if err != nil { return err } - cwd, err := os.Getwd() - if err != nil { - return errors.Errorf("failed to get working directory: %w", err) - } - dockerFuncDir := utils.ToDockerPath(filepath.Join(cwd, utils.FunctionsDir)) env = append(env, fmt.Sprintf("SUPABASE_URL=http://%s:8000", utils.KongAliases[0]), "SUPABASE_ANON_KEY="+utils.Config.Auth.AnonKey, @@ -121,7 +116,6 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, "SUPABASE_DB_URL="+dbUrl, "SUPABASE_INTERNAL_JWT_SECRET="+utils.Config.Auth.JwtSecret, fmt.Sprintf("SUPABASE_INTERNAL_HOST_PORT=%d", utils.Config.Api.Port), - "SUPABASE_INTERNAL_FUNCTIONS_PATH="+dockerFuncDir, ) if viper.GetBool("DEBUG") { env = append(env, "SUPABASE_INTERNAL_DEBUG=true") @@ -130,6 +124,10 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, env = append(env, "SUPABASE_INTERNAL_WALLCLOCK_LIMIT_SEC=0") } // 3. Parse custom import map + cwd, err := os.Getwd() + if err != nil { + return errors.Errorf("failed to get working directory: %w", err) + } binds, functionsConfigString, err := populatePerFunctionConfigs(cwd, importMapPath, noVerifyJWT, fsys) if err != nil { return err diff --git a/internal/functions/serve/templates/main.ts b/internal/functions/serve/templates/main.ts index 01afbfeb0..e94b183ac 100644 --- a/internal/functions/serve/templates/main.ts +++ b/internal/functions/serve/templates/main.ts @@ -2,6 +2,7 @@ import { STATUS_CODE, STATUS_TEXT, } from "https://deno.land/std/http/status.ts"; +import * as posix from "https://deno.land/std/path/posix/mod.ts"; import * as jose from "https://deno.land/x/jose@v4.13.1/index.ts"; @@ -28,7 +29,6 @@ const EXCLUDED_ENVS = ["HOME", "HOSTNAME", "PATH", "PWD"]; const JWT_SECRET = Deno.env.get("SUPABASE_INTERNAL_JWT_SECRET")!; const HOST_PORT = Deno.env.get("SUPABASE_INTERNAL_HOST_PORT")!; -const FUNCTIONS_PATH = Deno.env.get("SUPABASE_INTERNAL_FUNCTIONS_PATH")!; const DEBUG = Deno.env.get("SUPABASE_INTERNAL_DEBUG") === "true"; const FUNCTIONS_CONFIG_STRING = Deno.env.get( "SUPABASE_INTERNAL_FUNCTIONS_CONFIG", @@ -145,7 +145,7 @@ Deno.serve({ } } - const servicePath = `${FUNCTIONS_PATH}/${functionName}`; + const servicePath = posix.dirname(functionsConfig[functionName].entrypointPath); console.error(`serving the request with ${servicePath}`); // Ref: https://supabase.com/docs/guides/functions/limits @@ -168,6 +168,9 @@ Deno.serve({ // point, as their migration process will not be easy. const decoratorType = "tc39"; + const absEntrypoint = posix.join(Deno.cwd(), functionsConfig[functionName].entrypointPath); + const maybeEntrypoint = posix.toFileUrl(absEntrypoint).href; + try { const worker = await EdgeRuntime.userWorkers.create({ servicePath, @@ -180,7 +183,8 @@ Deno.serve({ customModuleRoot, cpuTimeSoftLimitMs, cpuTimeHardLimitMs, - decoratorType + decoratorType, + maybeEntrypoint }); const controller = new AbortController();