Skip to content

Commit

Permalink
Merge pull request containers#1506 from Luap99/pasta
Browse files Browse the repository at this point in the history
libnetwork: add pasta package to start pasta
  • Loading branch information
openshift-merge-robot authored Jun 15, 2023
2 parents 2d3d680 + d9ee72c commit 20def00
Showing 1 changed file with 140 additions and 0 deletions.
140 changes: 140 additions & 0 deletions libnetwork/pasta/pasta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// SPDX-License-Identifier: Apache-2.0
//
// pasta.go - Start pasta(1) for user-mode connectivity
//
// Copyright (c) 2022 Red Hat GmbH
// Author: Stefano Brivio <[email protected]>

// This file has been imported from the podman repository
// (libpod/networking_pasta_linux.go), for the full history see there.

package pasta

import (
"errors"
"fmt"
"os/exec"
"strings"

"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/sirupsen/logrus"
)

const (
BinaryName = "pasta"
)

type SetupOptions struct {
// Config used to get pasta options and binary path via HelperBinariesDir
Config *config.Config
// Netns is the path to the container Netns
Netns string
// Ports that should be forwarded in the container
Ports []types.PortMapping
// ExtraOptions are pasta(1) cli options, these will be appended after the
// pasta options from containers.conf to allow some form of overwrite.
ExtraOptions []string
}

// Setup start the pasta process for the given netns.
// The pasta binary is looked up in the HelperBinariesDir and $PATH.
// Note that there is no need any special cleanup logic, the pasta process will
// automatically exit when the netns path is deleted.
func Setup(opts *SetupOptions) error {
NoTCPInitPorts := true
NoUDPInitPorts := true
NoTCPNamespacePorts := true
NoUDPNamespacePorts := true
NoMapGW := true

path, err := opts.Config.FindHelperBinary(BinaryName, true)
if err != nil {
return fmt.Errorf("could not find pasta, the network namespace can't be configured: %w", err)
}

cmdArgs := []string{}
cmdArgs = append(cmdArgs, "--config-net")

for _, i := range opts.Ports {
protocols := strings.Split(i.Protocol, ",")
for _, protocol := range protocols {
var addr string

if i.HostIP != "" {
addr = fmt.Sprintf("%s/", i.HostIP)
}

switch protocol {
case "tcp":
cmdArgs = append(cmdArgs, "-t")
case "udp":
cmdArgs = append(cmdArgs, "-u")
default:
return fmt.Errorf("can't forward protocol: %s", protocol)
}

arg := fmt.Sprintf("%s%d-%d:%d-%d", addr,
i.HostPort,
i.HostPort+i.Range-1,
i.ContainerPort,
i.ContainerPort+i.Range-1)
cmdArgs = append(cmdArgs, arg)
}
}

// first append options set in the config
cmdArgs = append(cmdArgs, opts.Config.Network.PastaOptions...)
// then append the ones that were set on the cli
cmdArgs = append(cmdArgs, opts.ExtraOptions...)

for i, opt := range cmdArgs {
switch opt {
case "-t", "--tcp-ports":
NoTCPInitPorts = false
case "-u", "--udp-ports":
NoUDPInitPorts = false
case "-T", "--tcp-ns":
NoTCPNamespacePorts = false
case "-U", "--udp-ns":
NoUDPNamespacePorts = false
case "--map-gw":
NoMapGW = false
// not an actual pasta(1) option
cmdArgs = append(cmdArgs[:i], cmdArgs[i+1:]...)
}
}

if NoTCPInitPorts {
cmdArgs = append(cmdArgs, "-t", "none")
}
if NoUDPInitPorts {
cmdArgs = append(cmdArgs, "-u", "none")
}
if NoTCPNamespacePorts {
cmdArgs = append(cmdArgs, "-T", "none")
}
if NoUDPNamespacePorts {
cmdArgs = append(cmdArgs, "-U", "none")
}
if NoMapGW {
cmdArgs = append(cmdArgs, "--no-map-gw")
}

cmdArgs = append(cmdArgs, "--netns", opts.Netns)

logrus.Debugf("pasta arguments: %s", strings.Join(cmdArgs, " "))

// pasta forks once ready, and quits once we delete the target namespace
_, err = exec.Command(path, cmdArgs...).Output()
if err != nil {
exitErr := &exec.ExitError{}
if errors.As(err, &exitErr) {
return fmt.Errorf("pasta failed with exit code %d:\n%s",
exitErr.ExitCode(), exitErr.Stderr)
}
return fmt.Errorf("failed to start pasta: %w", err)
}

return nil
}

0 comments on commit 20def00

Please sign in to comment.