github.com/containerd/nerdctl@v1.7.7/pkg/containerutil/config.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package containerutil
    18  
    19  import (
    20  	"context"
    21  	"encoding/json"
    22  	"errors"
    23  	"fmt"
    24  	"runtime"
    25  	"strings"
    26  
    27  	"github.com/containerd/containerd"
    28  	"github.com/containerd/containerd/oci"
    29  	"github.com/containerd/nerdctl/pkg/labels"
    30  	"github.com/containerd/nerdctl/pkg/netutil/nettype"
    31  	"github.com/opencontainers/runtime-spec/specs-go"
    32  )
    33  
    34  // ReconfigNetContainer reconfigures the container's network namespace path.
    35  func ReconfigNetContainer(ctx context.Context, c containerd.Container, client *containerd.Client, lab map[string]string) error {
    36  	networksJSON, ok := lab[labels.Networks]
    37  	if !ok {
    38  		return nil
    39  	}
    40  	var networks []string
    41  	if err := json.Unmarshal([]byte(networksJSON), &networks); err != nil {
    42  		return err
    43  	}
    44  	netType, err := nettype.Detect(networks)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	if netType == nettype.Container {
    49  		network := strings.Split(networks[0], ":")
    50  		if len(network) != 2 {
    51  			return fmt.Errorf("invalid network: %s, should be \"container:<id|name>\"", networks[0])
    52  		}
    53  		targetCon, err := client.LoadContainer(ctx, network[1])
    54  		if err != nil {
    55  			return err
    56  		}
    57  		netNSPath, err := ContainerNetNSPath(ctx, targetCon)
    58  		if err != nil {
    59  			return err
    60  		}
    61  		spec, err := c.Spec(ctx)
    62  		if err != nil {
    63  			return err
    64  		}
    65  		err = c.Update(ctx, containerd.UpdateContainerOpts(
    66  			containerd.WithSpec(spec, oci.WithLinuxNamespace(
    67  				specs.LinuxNamespace{
    68  					Type: specs.NetworkNamespace,
    69  					Path: netNSPath,
    70  				}))))
    71  		if err != nil {
    72  			return err
    73  		}
    74  	}
    75  	return nil
    76  }
    77  
    78  // ReconfigPIDContainer reconfigures the container's spec options for sharing PID namespace.
    79  func ReconfigPIDContainer(ctx context.Context, c containerd.Container, client *containerd.Client, lab map[string]string) error {
    80  	targetContainerID, ok := lab[labels.PIDContainer]
    81  	if !ok {
    82  		return nil
    83  	}
    84  	if runtime.GOOS != "linux" {
    85  		return errors.New("--pid only supported on linux")
    86  	}
    87  	targetCon, err := client.LoadContainer(ctx, targetContainerID)
    88  	if err != nil {
    89  		return err
    90  	}
    91  	opts, err := GenerateSharingPIDOpts(ctx, targetCon)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	spec, err := c.Spec(ctx)
    96  	if err != nil {
    97  		return err
    98  	}
    99  	err = c.Update(ctx, containerd.UpdateContainerOpts(
   100  		containerd.WithSpec(spec, oci.Compose(opts...)),
   101  	))
   102  	if err != nil {
   103  		return err
   104  	}
   105  	return nil
   106  }