Skip to content

Commit

Permalink
refactor(tunnels): centralize tunnel management and integrate with de…
Browse files Browse the repository at this point in the history
…ployment process
  • Loading branch information
yarlson committed Jan 20, 2025
1 parent a3a83bc commit f16d562
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 44 deletions.
42 changes: 2 additions & 40 deletions cmd/tunnels.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package cmd

import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"

"github.com/spf13/cobra"

"github.com/yarlson/ftl/pkg/config"
"github.com/yarlson/ftl/pkg/console"
"github.com/yarlson/ftl/pkg/tunnel"
)
Expand Down Expand Up @@ -40,12 +38,7 @@ func runTunnels(cmd *cobra.Command, args []string) {
return
}

// Build the same list of tunnels
tunnels, err := collectDependencyTunnels(cfg)
if err != nil {
spinner.ErrorWithMessagef("Failed to collect dependencies: %v", err)
return
}
tunnels := tunnel.CollectDependencyTunnels(cfg)
if len(tunnels) == 0 {
spinner.ErrorWithMessage("No dependencies with ports found in the configuration.")
return
Expand All @@ -55,12 +48,11 @@ func runTunnels(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// >>>> NEW: just call our StartTunnels function <<<<
err = tunnel.StartTunnels(
ctx,
cfg.Server.Host, cfg.Server.Port,
cfg.Server.User, cfg.Server.SSHKey,
toTunnelConfigs(tunnels), // see helper below
tunnels,
)
if err != nil {
spinner.ErrorWithMessagef("Failed to establish tunnels: %v", err)
Expand All @@ -82,33 +74,3 @@ func runTunnels(cmd *cobra.Command, args []string) {
cancel()
time.Sleep(1 * time.Second)
}

type TunnelConfig struct {
LocalPort string
RemoteAddr string
}

func collectDependencyTunnels(cfg *config.Config) ([]TunnelConfig, error) {
var tunnels []TunnelConfig
for _, dep := range cfg.Dependencies {
for _, port := range dep.Ports {
tunnels = append(tunnels, TunnelConfig{
LocalPort: fmt.Sprintf("%d", port),
RemoteAddr: fmt.Sprintf("localhost:%d", port),
})
}
}
return tunnels, nil
}

// Helper that converts our cmd-level TunnelConfig into the tunnel package's TunnelConfig
func toTunnelConfigs(src []TunnelConfig) []tunnel.TunnelConfig {
result := make([]tunnel.TunnelConfig, 0, len(src))
for _, s := range src {
result = append(result, tunnel.TunnelConfig{
LocalPort: s.LocalPort,
RemoteAddr: s.RemoteAddr,
})
}
return result
}
12 changes: 12 additions & 0 deletions pkg/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,23 @@ func (d *Deployment) Deploy(ctx context.Context, project string, cfg *config.Con
return fmt.Errorf("failed to deploy dependencies: %w", err)
}

// Start tunnels if needed
tunnelCtx, tunnelCancel := context.WithCancel(ctx)
defer tunnelCancel()

if hasLocalHooks(cfg) {
if err := d.startTunnels(tunnelCtx, cfg); err != nil {
return fmt.Errorf("failed to start tunnels: %w", err)
}
}

// Deploy services
if err := d.deployServices(ctx, project, cfg.Services); err != nil {
return fmt.Errorf("failed to deploy services: %w", err)
}

tunnelCancel()

// Setup proxy
if err := d.startProxy(ctx, project, cfg); err != nil {
return fmt.Errorf("failed to start proxy: %w", err)
Expand Down
36 changes: 36 additions & 0 deletions pkg/deployment/tunnels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package deployment

import (
"context"
"fmt"

"github.com/yarlson/ftl/pkg/config"
"github.com/yarlson/ftl/pkg/tunnel"
)

func hasLocalHooks(cfg *config.Config) bool {
for _, service := range cfg.Services {
if service.Hooks != nil && service.Hooks.Pre != nil && service.Hooks.Pre.Local != "" {
return true
}
if service.Hooks != nil && service.Hooks.Post != nil && service.Hooks.Post.Local != "" {
return true
}
}

return false
}

func (d *Deployment) startTunnels(ctx context.Context, cfg *config.Config) error {
err := tunnel.StartTunnels(
ctx,
cfg.Server.Host, cfg.Server.Port,
cfg.Server.User, cfg.Server.SSHKey,
tunnel.CollectDependencyTunnels(cfg),
)
if err != nil {
return fmt.Errorf("failed to establish tunnels: %w", err)
}

return nil
}
22 changes: 18 additions & 4 deletions pkg/tunnel/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package tunnel
import (
"context"
"fmt"
"github.com/yarlson/ftl/pkg/config"
"sync"
"time"

"github.com/yarlson/ftl/pkg/ssh"
)

// TunnelConfig describes which local port should forward to which remote address.
type TunnelConfig struct {
// Config describes which local port should forward to which remote address.
type Config struct {
LocalPort string
RemoteAddr string
}
Expand All @@ -21,7 +22,7 @@ func StartTunnels(
host string,
port int,
user, sshKey string,
tunnels []TunnelConfig,
tunnels []Config,
) error {
if len(tunnels) == 0 {
return fmt.Errorf("no tunnels to establish")
Expand All @@ -32,7 +33,7 @@ func StartTunnels(

for _, t := range tunnels {
wg.Add(1)
go func(tun TunnelConfig) {
go func(tun Config) {
defer wg.Done()

err := ssh.CreateSSHTunnel(ctx, host, port, user, sshKey, tun.LocalPort, tun.RemoteAddr)
Expand All @@ -59,3 +60,16 @@ func StartTunnels(

return nil
}

func CollectDependencyTunnels(cfg *config.Config) []Config {
var tunnels []Config
for _, dep := range cfg.Dependencies {
for _, port := range dep.Ports {
tunnels = append(tunnels, Config{
LocalPort: fmt.Sprintf("%d", port),
RemoteAddr: fmt.Sprintf("localhost:%d", port),
})
}
}
return tunnels
}

0 comments on commit f16d562

Please sign in to comment.