github.com/containerd/nerdctl@v1.7.7/pkg/bypass4netnsutil/bypass4netnsutil.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 bypass4netnsutil
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"os"
    23  	"path/filepath"
    24  	"strconv"
    25  
    26  	"github.com/containerd/containerd/containers"
    27  	"github.com/containerd/containerd/oci"
    28  	"github.com/containerd/nerdctl/pkg/labels"
    29  	"github.com/opencontainers/runtime-spec/specs-go"
    30  	b4nnoci "github.com/rootless-containers/bypass4netns/pkg/oci"
    31  )
    32  
    33  func generateSecurityOpt(listenerPath string) (oci.SpecOpts, error) {
    34  	opt := func(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error {
    35  		if s.Linux.Seccomp == nil {
    36  			s.Linux.Seccomp = b4nnoci.GetDefaultSeccompProfile(listenerPath)
    37  		} else {
    38  			sc, err := b4nnoci.TranslateSeccompProfile(*s.Linux.Seccomp, listenerPath)
    39  			if err != nil {
    40  				return err
    41  			}
    42  			s.Linux.Seccomp = sc
    43  		}
    44  		return nil
    45  	}
    46  	return opt, nil
    47  }
    48  
    49  func GenerateBypass4netnsOpts(securityOptsMaps map[string]string, labelMaps map[string]string, id string) ([]oci.SpecOpts, error) {
    50  	b4nn, ok := labelMaps[labels.Bypass4netns]
    51  	if !ok {
    52  		return nil, nil
    53  	}
    54  
    55  	b4nnEnable, err := strconv.ParseBool(b4nn)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	if !b4nnEnable {
    61  		return nil, nil
    62  	}
    63  
    64  	socketPath, err := GetSocketPathByID(id)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	err = CreateSocketDir()
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	opts := []oci.SpecOpts{}
    75  	opt, err := generateSecurityOpt(socketPath)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  	opts = append(opts, opt)
    80  
    81  	return opts, nil
    82  }
    83  
    84  func getXDGRuntimeDir() (string, error) {
    85  	if xrd := os.Getenv("XDG_RUNTIME_DIR"); xrd != "" {
    86  		return xrd, nil
    87  	}
    88  	return "", fmt.Errorf("environment variable XDG_RUNTIME_DIR is not set")
    89  }
    90  
    91  func CreateSocketDir() error {
    92  	xdgRuntimeDir, err := getXDGRuntimeDir()
    93  	if err != nil {
    94  		return err
    95  	}
    96  	dirPath := filepath.Join(xdgRuntimeDir, "bypass4netns")
    97  	if _, err := os.Stat(dirPath); os.IsNotExist(err) {
    98  		err = os.MkdirAll(dirPath, 0775)
    99  		if err != nil {
   100  			return err
   101  		}
   102  	}
   103  
   104  	return nil
   105  }
   106  
   107  func GetBypass4NetnsdDefaultSocketPath() (string, error) {
   108  	xdgRuntimeDir, err := getXDGRuntimeDir()
   109  	if err != nil {
   110  		return "", err
   111  	}
   112  
   113  	return filepath.Join(xdgRuntimeDir, "bypass4netnsd.sock"), nil
   114  }
   115  
   116  func GetSocketPathByID(id string) (string, error) {
   117  	xdgRuntimeDir, err := getXDGRuntimeDir()
   118  	if err != nil {
   119  		return "", err
   120  	}
   121  
   122  	socketPath := filepath.Join(xdgRuntimeDir, "bypass4netns", id[0:15]+".sock")
   123  	return socketPath, nil
   124  }
   125  
   126  func GetPidFilePathByID(id string) (string, error) {
   127  	xdgRuntimeDir, err := getXDGRuntimeDir()
   128  	if err != nil {
   129  		return "", err
   130  	}
   131  
   132  	socketPath := filepath.Join(xdgRuntimeDir, "bypass4netns", id[0:15]+".pid")
   133  	return socketPath, nil
   134  }
   135  
   136  func IsBypass4netnsEnabled(annotations map[string]string) (bool, error) {
   137  	if b4nn, ok := annotations[labels.Bypass4netns]; ok {
   138  		b4nnEnable, err := strconv.ParseBool(b4nn)
   139  		if err != nil {
   140  			return false, err
   141  		}
   142  
   143  		return b4nnEnable, nil
   144  	}
   145  
   146  	return false, nil
   147  }