github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/infra/container/client/docker/container.go (about)

     1  // Copyright © 2021 Alibaba Group Holding Ltd.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package docker
    16  
    17  import (
    18  	"github.com/docker/docker/api/types"
    19  	"github.com/docker/docker/api/types/container"
    20  	"github.com/docker/docker/api/types/mount"
    21  	"github.com/docker/docker/api/types/network"
    22  	"github.com/sirupsen/logrus"
    23  
    24  	"github.com/sealerio/sealer/pkg/infra/container/client"
    25  )
    26  
    27  const (
    28  	CgroupNoneDriver = "none"
    29  )
    30  
    31  func (p *Provider) getUserNsMode() (container.UsernsMode, error) {
    32  	sysInfo, err := p.DockerClient.Info(p.Ctx)
    33  	if err != nil {
    34  		return "", err
    35  	}
    36  
    37  	var usernsMode container.UsernsMode
    38  	for _, opt := range sysInfo.SecurityOptions {
    39  		if opt == "name=userns" {
    40  			usernsMode = "host"
    41  		}
    42  	}
    43  	return usernsMode, err
    44  }
    45  
    46  func (p *Provider) setContainerMount(opts *client.CreateOptsForContainer) []mount.Mount {
    47  	mounts := DefaultMounts()
    48  	if opts.Mount != nil {
    49  		mounts = append(mounts, opts.Mount...)
    50  	}
    51  	return mounts
    52  }
    53  
    54  func (p *Provider) RunContainer(opts *client.CreateOptsForContainer) (string, error) {
    55  	//docker run --hostname master1 --name master1
    56  	//--privileged
    57  	//--security-opt seccomp=unconfined --security-opt apparmor=unconfined
    58  	//--tmpfs /tmp --tmpfs /run
    59  	//--volume /var --volume /lib/modules:/lib/modules:ro
    60  	//--device /dev/fuse
    61  	//--detach --tty --restart=on-failure:1 --init=false sealer-io/sealer-base-image:latest
    62  	networkID, err := p.PrepareNetworkResource(opts.NetworkName)
    63  	if err != nil {
    64  		return "", err
    65  	}
    66  
    67  	_, err = p.PullImage(opts.ImageName)
    68  	if err != nil {
    69  		return "", err
    70  	}
    71  
    72  	mod, _ := p.getUserNsMode()
    73  	mounts := p.setContainerMount(opts)
    74  	falseOpts := false
    75  	resp, err := p.DockerClient.ContainerCreate(p.Ctx, &container.Config{
    76  		Image:        opts.ImageName,
    77  		Tty:          true,
    78  		Labels:       opts.ContainerLabel,
    79  		Hostname:     opts.ContainerHostName,
    80  		AttachStdin:  false,
    81  		AttachStdout: false,
    82  		AttachStderr: false,
    83  	},
    84  		&container.HostConfig{
    85  			UsernsMode: mod,
    86  			SecurityOpt: []string{
    87  				"seccomp=unconfined", "apparmor=unconfined",
    88  			},
    89  			RestartPolicy: container.RestartPolicy{
    90  				Name:              "on-failure",
    91  				MaximumRetryCount: 1,
    92  			},
    93  			Init:         &falseOpts,
    94  			CgroupnsMode: "host",
    95  			Privileged:   true,
    96  			Mounts:       mounts,
    97  		}, &network.NetworkingConfig{
    98  			EndpointsConfig: map[string]*network.EndpointSettings{
    99  				opts.NetworkName: {
   100  					NetworkID: networkID,
   101  				},
   102  			},
   103  		}, nil, opts.ContainerName)
   104  
   105  	if err != nil {
   106  		return "", err
   107  	}
   108  
   109  	err = p.DockerClient.ContainerStart(p.Ctx, resp.ID, types.ContainerStartOptions{})
   110  	if err != nil {
   111  		return "", err
   112  	}
   113  	logrus.Infof("create container %s successfully", opts.ContainerName)
   114  	return resp.ID, nil
   115  }
   116  
   117  func (p *Provider) GetContainerInfo(containerID string, networkName string) (*client.Container, error) {
   118  	resp, err := p.DockerClient.ContainerInspect(p.Ctx, containerID)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	return &client.Container{
   123  		ContainerName:     resp.Name,
   124  		ContainerIP:       resp.NetworkSettings.Networks[networkName].IPAddress,
   125  		ContainerHostName: resp.Config.Hostname,
   126  		ContainerLabel:    resp.Config.Labels,
   127  		Status:            resp.State.Status,
   128  	}, nil
   129  }
   130  
   131  func (p *Provider) GetContainerIDByIP(containerIP string, networkName string) (string, error) {
   132  	resp, err := p.DockerClient.ContainerList(p.Ctx, types.ContainerListOptions{})
   133  	if err != nil {
   134  		return "", err
   135  	}
   136  
   137  	for _, item := range resp {
   138  		if net, ok := item.NetworkSettings.Networks[networkName]; ok {
   139  			if containerIP == net.IPAddress {
   140  				return item.ID, nil
   141  			}
   142  		}
   143  	}
   144  	return "", err
   145  }
   146  
   147  func (p *Provider) RmContainer(containerID string) error {
   148  	err := p.DockerClient.ContainerRemove(p.Ctx, containerID, types.ContainerRemoveOptions{
   149  		RemoveVolumes: true,
   150  		Force:         true,
   151  	})
   152  
   153  	if err != nil {
   154  		return err
   155  	}
   156  
   157  	logrus.Infof("delete container %s successfully", containerID)
   158  	return nil
   159  }
   160  
   161  func (p *Provider) GetServerInfo() (*client.DockerInfo, error) {
   162  	sysInfo, err := p.DockerClient.Info(p.Ctx)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  
   167  	var dInfo client.DockerInfo
   168  
   169  	// When CgroupDriver == "none", the MemoryLimit/PidsLimit/CPUShares
   170  	// values are meaningless and need to be considered false.
   171  	// https://github.com/moby/moby/issues/42151
   172  	dInfo.CgroupVersion = sysInfo.CgroupVersion
   173  	dInfo.StorageDriver = sysInfo.Driver
   174  	dInfo.SecurityOptions = sysInfo.SecurityOptions
   175  	dInfo.CgroupDriver = sysInfo.CgroupDriver
   176  	if sysInfo.CgroupDriver == CgroupNoneDriver {
   177  		return &dInfo, nil
   178  	}
   179  	dInfo.MemoryLimit = sysInfo.MemoryLimit
   180  	dInfo.PidsLimit = sysInfo.PidsLimit
   181  	dInfo.CPUShares = sysInfo.CPUShares
   182  	dInfo.CPUNumber = sysInfo.NCPU
   183  	return &dInfo, nil
   184  }