Upgrade Funnel¶
Use this guide when upgrading to the unreleased Go package reorganization and the accompanying configuration and scheduler changes. It covers downstream Go applications, authorization plugins, and existing deployments.
The Go package moves preserve TES message field numbers, JSON names, and service identities. They do not preserve Go import paths. Configuration schema changes have separate migration requirements described below.
Prepare the deployment¶
- Back up the task database, configuration, custom templates, and HPC submission records. Test the upgrade and rollback against a restored copy first.
- Finish tasks whose Kubernetes storage plans use versions 1, 2, or 3. Use a compatible older binary to clean up their Jobs before upgrading.
- For HPC jobs submitted without trusted submission records, cancel them using the scheduler's own command before upgrading.
- Stop older Funnel servers, schedulers, and nodes before starting upgraded instances. Upgrade the participating servers, nodes, workers, and plugins together. Do not mix scheduler versions during the assignment migration.
See Kubernetes storage ownership and upgrades and scheduler assignment storage upgrades for the backend-specific requirements.
Update Go imports¶
Use github.com/calypr/funnel as the module prefix. Replace the former
github.com/ohsu-comp-bio/funnel prefix if your application still uses it.
The paths in this table are relative to that prefix.
| Previous import or use | Replacement |
|---|---|
tes request, response, and enum types |
api/tes |
tes.NewClient and tes.Client |
client/tes.NewClient and client/tes.Client |
config schema types |
api/config |
logger configuration schema types |
api/logger |
plugins/proto messages and plugins/shared interfaces, handshake, and adapters |
api/plugin |
server, compute, worker, storage, database, events, and other application implementations |
Private under internal/. Use the REST client or plugin contracts for external integrations. |
There are no forwarding packages for the old imports. Go rejects external
imports of internal/ packages. The generated Go gRPC and gateway bindings are
also internal. Use the REST client, or generate bindings in your own module if
you maintain a direct gRPC integration.
Replace tes.Marshaler, tes.MarshalToString, and the client's Marshaler
field with explicit google.golang.org/protobuf/encoding/protojson calls.
Application defaults, YAML loading, validation, redaction, asset access, runtime
logging, and plugin process management are no longer public library functions.
For plugins, use the configuration supplied by the host. For external tooling,
own the required configuration loading and validation instead of importing the
application implementation. funnel examples default-config prints the bundled
configuration example.
The public api/config and api/logger packages contain schema types. They do
not replace the old runtime helpers such as config.DefaultConfig, ParseFile,
ToYamlFile, or logger.NewLogger. The former util helpers have moved to their
owning packages or the standard library. Build metadata is public in version.
Configure the REST client¶
Import the client separately from the TES models. Credentials can come from the environment or be set on the client:
package example
import (
"context"
"net/http"
"time"
"github.com/calypr/funnel/api/tes"
tesclient "github.com/calypr/funnel/client/tes"
)
func GetTask(ctx context.Context, address, token, id string) (*tes.Task, error) {
client, err := tesclient.NewClient(address,
tesclient.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}))
if err != nil {
return nil, err
}
client.Token = token
return client.GetTask(ctx, &tes.GetTaskRequest{Id: id, View: "FULL"})
}
NewClient continues to read FUNNEL_SERVER_USER, FUNNEL_SERVER_PASSWORD,
FUNNEL_SERVER_TOKEN, and FUNNEL_ALLOW_INSECURE_CREDENTIALS at construction.
These variables remain supported by both Go applications and the CLI. Set
User, Password, or Token afterward, or supply a ClientOption, to override
the environment defaults. A token takes precedence over Basic credentials.
Use HTTPS for credentials sent to remote hosts. The REST client allows loopback
HTTP. For deployments that deliberately permit remote plaintext credentials,
pass tesclient.WithInsecureCredentials() in Go or set
FUNNEL_ALLOW_INSECURE_CREDENTIALS=true for Go clients, the CLI, and connecting processes.
Authenticated remote plaintext gRPC connections require the explicit setting
or a secure tunnel ending on loopback. The opt-in also permits authenticated
HTTPS-to-HTTP redirects. See remote server connections.
Follow pagination tokens when listing tasks or nodes. Node listings default to 500 entries and accept page sizes from 1 through 1000. Upgrade older gRPC node clients to use the new pagination fields.
See Go packages and the TES client for the full package layout and client behavior.
Rebuild authorization plugins¶
Update plugins to import api/config, api/tes, and api/plugin. Consolidate
the old plugins/proto and plugins/shared imports into one api/plugin
import. Implement plugin.Authorize, use plugin.Handshake, and choose
plugin.AuthorizePlugin for net/rpc or plugin.AuthorizeGRPCPlugin for gRPC.
Use your own logger instead of the former plugins/shared.Logger.
Rebuild plugin binaries against the same Funnel module version as the upgraded host and deploy them together. The net/rpc adapters now carry complete protobuf messages inside Gob. This preserves optional TES fields and configuration oneofs without global Gob registrations. The encoding differs from older net/rpc binaries, so both peers must be rebuilt. The gRPC wire format is unchanged. Host process loading remains internal.
Return the complete edited configuration¶
Local and Kubernetes backends now merge plugin responses with
WithOverwriteWithEmptyValue. False, zero, empty strings, cleared collections,
and removed map entries can clear inherited settings. Plugins that return
partial configurations can erase required server settings.
Clone the supplied configuration, edit that copy, and return it with the task:
package example
import (
"github.com/calypr/funnel/api/config"
"github.com/calypr/funnel/api/plugin"
"github.com/calypr/funnel/api/tes"
"google.golang.org/protobuf/proto"
)
func ConfigureTask(input *config.Config, task *tes.Task) *plugin.JobResponse {
effective := proto.Clone(input).(*config.Config)
effective.Worker.LeaveWorkDir = false
return &plugin.JobResponse{Code: 200, Config: effective, Task: task}
}
Preserve settings unrelated to your changes. Kubernetes task overrides cannot
change the backend's Jobs namespace. The server validates the resulting task
configuration. See the Go package contracts
and api/plugin/README.md in the source checkout.
Migrate deployment configuration¶
Remove retired keys instead of leaving unused sections in a full configuration. The strict configuration parser rejects unknown fields.
- Remove
Elastic, even if another database is selected. Elasticsearch users must migrate their data to a supported backend. - Set
FTPStorage.Endpointwhen using configured FTP credentials. The hostname and port must match the requested origin. See FTP credentials. - For Slurm, PBS, HTCondor, and Grid Engine, set
HPCStateDirto an absolute, persistent controller directory with mode0700. Keep it outside task work directories and enabled local-storage roots. Use a boundedLocalStorage.AllowedDirslist or disable local storage. Back up this directory with the database. See trusted HPC submission records. - Update custom runtime templates that use
index .Env "KEY"orindex .Tags "KEY". Use.GetEnvArgs,.GetTagArgs, or arangewitheq. Runtime argument placeholders must reach the runtime unchanged. See compute deployment templates.
Replace retired Kubernetes storage settings¶
If your configuration uses retired storage keys, migrate those definitions to
native objects under Kubernetes.Storage.
The retired names include PVCMode, StorageClassName, SharedPVCName,
S3FilesFilesystemId, Bindings, and MountedInputs. Replace
MountedRead.WorkerMount and MountedWrite.WorkerMount with Volume, using
SubPath when selecting one of several mounts of a volume.
Use a static logical name such as workspace for a PVC template's
metadata.name. Funnel generates <taskID>-workspace; remove old volume entries
that refer to the rendered task-specific claim name. Keep WorkerImage
independent of the storage definition.
The legacy PVTemplate, PVCTemplate, and JobTemplate settings remain a
fallback when Storage is absent. Their presence alone does not require a
conversion to native storage configuration.
For old Chicago binary configurations, export using the original schema before
converting to named configuration. Its S3FilesFilesystemId field number
conflicts with upstream ForbiddenPathPrefixes. Loading that binary directly
with the canonical schema cannot distinguish the two fields. Move the filesystem
ID into the native CSI PV template and rebuild affected plugins.
See Kubernetes storage and mounted inputs for complete migration examples.
Upgrade scheduler storage¶
Convert standalone MongoDB deployments to a replica set or sharded cluster before upgrading. A single-node replica set is sufficient for development. Changing only the connection URI does not enable transactions. Follow the MongoDB upgrade procedure.
At first startup, the upgraded scheduler imports active assignments into durable claims. Resolve reported ownership conflicts or duplicate MongoDB IDs before resuming submissions. Do not bypass failed migrations by running older servers alongside the upgraded deployment. See assignment storage upgrades and MongoDB startup migration.
Update development and deployment automation¶
Keep provisioning scripts, service definitions, and infrastructure manifests in
operator-maintained deployment code. The bundled GCE provisioning, VM installer,
and systemd examples have been removed. Runtime compute backends and container
images remain available. The root executable and CLI remain reachable through
go install github.com/calypr/funnel.
Update scripts that refer to the former repository layout:
- Read documentation from
docs/; Hugo configuration stays inwebsite/. - Use
tests/integration,tests/e2e, andtests/benchmarksfor the respective suites. Shared integration configuration files live intests/testdata/config. - Run
make protofor schema generation through the Buf configuration inapi/. Run direct Buf commands fromapi/. Proto imports are relative to that directory. Updateplugins/proto/plugin.prototoplugin/plugin.proto,events/events.prototointernal/events/events.proto, andcompute/scheduler/scheduler.prototointernal/scheduler/scheduler.proto. The TES service declaration is now ininternal/tesrpc/service.proto; shared TES messages remain intes/tes.proto. Message namespaces and service names remain unchanged, but file moves break Buf'sFILEcompatibility policy. - Update custom linker flags to use
github.com/calypr/funnel/version. - Remove calls to the retired
bundle-examplesMake target.
The source build currently requires Go 1.27.3, as declared in go.mod.
Integration tests clean up generated files by default. Pass
-funnel-keep-artifacts when retaining them for debugging. Resources still close
when files are retained. See developer test instructions
and tests/README.md in the source checkout.
Verify the upgrade¶
Build and test downstream applications and rebuilt plugins against the selected Funnel version. In a test deployment, verify authenticated task creation, retrieval, cancellation, input downloads, output publication, and pagination. If authentication is configured, check that unauthorized requests remain rejected. Check that plugins preserve unrelated configuration settings when clearing individual values.
Confirm that startup migrations finish before resuming normal submissions. Keep backups and older binaries until the upgraded deployment and its rollback procedure have been verified.