package main import ( "context" "log" "os" "os/exec" "path/filepath" "time" ) const ( defaultUpdateDir = "/app/update_data" defaultLogDir = "/app/log" defaultSchema = "public" defaultTimeout = 15 * time.Minute ) func main() { logger := log.New(os.Stdout, "[sync] ", log.LstdFlags) ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() updateDir := env("USER_PROGRAM_UPDATE_DIR", defaultUpdateDir) logDir := env("USER_PROGRAM_IMPORT_LOG_DIR", defaultLogDir) schema := env("USER_PROGRAM_INFO_SCHEMA", defaultSchema) ensureDir(updateDir, logger) ensureDir(logDir, logger) if err := runCmd(ctx, logger, "user-program-dump", map[string]string{ "USER_PROGRAM_UPDATE_DIR": updateDir, }); err != nil { logger.Fatalf("dump failed: %v", err) } if err := runCmd(ctx, logger, "user-program-import", map[string]string{ "USER_PROGRAM_UPDATE_DIR": updateDir, "USER_PROGRAM_IMPORT_LOG_DIR": logDir, "USER_PROGRAM_INFO_SCHEMA": schema, }); err != nil { logger.Fatalf("import failed: %v", err) } logger.Printf("sync completed (update_dir=%s, log_dir=%s, schema=%s)", updateDir, logDir, schema) } func runCmd(ctx context.Context, logger *log.Logger, command string, extraEnv map[string]string) error { cmd := exec.CommandContext(ctx, command) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Env = os.Environ() for k, v := range extraEnv { if v == "" { continue } cmd.Env = append(cmd.Env, k+"="+v) } logger.Printf("running %s", filepath.Base(command)) return cmd.Run() } func ensureDir(path string, logger *log.Logger) { if err := os.MkdirAll(path, 0o755); err != nil { logger.Fatalf("failed to create dir %s: %v", path, err) } } func env(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback }