github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/guest/guest.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 guest
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/alibaba/sealer/pkg/runtime"
    21  	"github.com/alibaba/sealer/utils/platform"
    22  
    23  	v1 "github.com/alibaba/sealer/types/api/v1"
    24  
    25  	"github.com/alibaba/sealer/utils"
    26  
    27  	"github.com/moby/buildkit/frontend/dockerfile/shell"
    28  
    29  	v2 "github.com/alibaba/sealer/types/api/v2"
    30  
    31  	"github.com/alibaba/sealer/common"
    32  	"github.com/alibaba/sealer/pkg/image/store"
    33  	"github.com/alibaba/sealer/utils/ssh"
    34  )
    35  
    36  type Interface interface {
    37  	Apply(cluster *v2.Cluster) error
    38  	Delete(cluster *v2.Cluster) error
    39  }
    40  
    41  type Default struct {
    42  	imageStore store.ImageStore
    43  }
    44  
    45  func NewGuestManager() (Interface, error) {
    46  	is, err := store.NewDefaultImageStore()
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	return &Default{imageStore: is}, nil
    52  }
    53  
    54  func (d *Default) Apply(cluster *v2.Cluster) error {
    55  	var (
    56  		clusterRootfs = common.DefaultTheClusterRootfsDir(cluster.Name)
    57  		ex            = shell.NewLex('\\')
    58  	)
    59  
    60  	image, err := d.imageStore.GetByName(cluster.Spec.Image, platform.GetDefaultPlatform())
    61  	if err != nil {
    62  		return fmt.Errorf("get cluster image failed, %s", err)
    63  	}
    64  	cmdArgs := d.getGuestCmdArg(cluster, image)
    65  	cmd := d.getGuestCmd(cluster, image)
    66  	sshClient, err := ssh.NewStdoutSSHClient(runtime.GetMaster0Ip(cluster), cluster)
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	for _, value := range cmd {
    72  		if value == "" {
    73  			continue
    74  		}
    75  		cmdline, err := ex.ProcessWordWithMap(value, cmdArgs)
    76  		if err != nil {
    77  			return fmt.Errorf("failed to render build args: %v", err)
    78  		}
    79  
    80  		if err := sshClient.CmdAsync(cluster.GetMaster0IP(), fmt.Sprintf(common.CdAndExecCmd, clusterRootfs, cmdline)); err != nil {
    81  			return err
    82  		}
    83  	}
    84  
    85  	return nil
    86  }
    87  
    88  func (d *Default) getGuestCmd(cluster *v2.Cluster, image *v1.Image) []string {
    89  	var (
    90  		cmd        = image.Spec.ImageConfig.Cmd.Parent
    91  		clusterCmd = cluster.Spec.CMD
    92  		imageType  = image.Spec.ImageConfig.ImageType
    93  	)
    94  
    95  	// application image: if cluster cmd not nil, use cluster cmd directly
    96  	if imageType == common.AppImage {
    97  		if len(clusterCmd) != 0 {
    98  			return clusterCmd
    99  		}
   100  		return image.Spec.ImageConfig.Cmd.Current
   101  	}
   102  
   103  	// normal image: if cluster cmd not nil, use cluster cmd as current cmd
   104  	if len(clusterCmd) != 0 {
   105  		return utils.MergeSlice(cmd, clusterCmd)
   106  	}
   107  	return utils.MergeSlice(cmd, image.Spec.ImageConfig.Cmd.Current)
   108  }
   109  
   110  func (d *Default) getGuestCmdArg(cluster *v2.Cluster, image *v1.Image) map[string]string {
   111  	var (
   112  		base        map[string]string
   113  		clusterArgs = cluster.Spec.CMDArgs
   114  		imageType   = image.Spec.ImageConfig.ImageType
   115  	)
   116  
   117  	if imageType == common.AppImage {
   118  		base = image.Spec.ImageConfig.Args.Current
   119  	} else {
   120  		base = utils.MergeMap(image.Spec.ImageConfig.Args.Parent, image.Spec.ImageConfig.Args.Current)
   121  	}
   122  
   123  	for k, v := range utils.ConvertEnvListToMap(clusterArgs) {
   124  		base[k] = v
   125  	}
   126  	return base
   127  }
   128  
   129  func (d Default) Delete(cluster *v2.Cluster) error {
   130  	panic("implement me")
   131  }