github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/build/kubefile/parser/app_handler.go (about)

     1  // Copyright © 2022 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 parser
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"strings"
    21  
    22  	"github.com/pkg/errors"
    23  	"github.com/sealerio/sealer/build/kubefile/command"
    24  	v1 "github.com/sealerio/sealer/pkg/define/application/v1"
    25  	"github.com/sealerio/sealer/pkg/define/application/version"
    26  )
    27  
    28  func (kp *KubefileParser) processApp(node *Node, result *KubefileResult) (version.VersionedApplication, error) {
    29  	var (
    30  		appName     = ""
    31  		localFiles  = []string{}
    32  		remoteFiles = []string{}
    33  		filesToCopy = []string{}
    34  	)
    35  
    36  	// first node value is the command
    37  	for ptr := node.Next; ptr != nil; ptr = ptr.Next {
    38  		val := ptr.Value
    39  		// record the first word to be the app name
    40  		if appName == "" {
    41  			appName = val
    42  			continue
    43  		}
    44  		switch {
    45  		//
    46  		case isLocal(val):
    47  			localFiles = append(localFiles, trimLocal(val))
    48  		case isRemote(val):
    49  			remoteFiles = append(remoteFiles, val)
    50  		default:
    51  			return nil, errors.New("source schema should be specified with https:// http:// local:// in APP")
    52  		}
    53  	}
    54  
    55  	if appName == "" {
    56  		return nil, errors.New("app name should be specified in the app cmd")
    57  	}
    58  
    59  	// TODO clean the app directory first before putting files into it.
    60  	// this will rely on the storage interface
    61  	if len(localFiles) > 0 {
    62  		filesToCopy = append(filesToCopy, localFiles...)
    63  	}
    64  
    65  	// for the remote files
    66  	// 1. create a temp dir under the build context
    67  	// 2. download remote files to the temp dir
    68  	// 3. append the temp files to filesToCopy
    69  	if len(remoteFiles) > 0 {
    70  		tmpDir, err := os.MkdirTemp(kp.buildContext, "sealer-remote-files")
    71  		if err != nil {
    72  			return nil, errors.Errorf("failed to create remote context: %s", err)
    73  		}
    74  
    75  		files, err := downloadRemoteFiles(tmpDir, remoteFiles)
    76  		if err != nil {
    77  			return nil, err
    78  		}
    79  
    80  		filesToCopy = append(filesToCopy, files...)
    81  		// append it to the legacy.
    82  		// it will be deleted by CleanContext
    83  		result.legacyContext.directories = append(result.legacyContext.directories, tmpDir)
    84  	}
    85  
    86  	destDir := kp.appRootPathFunc(appName)
    87  	tmpLine := strings.Join(append([]string{command.Copy}, append(filesToCopy, destDir)...), " ")
    88  	result.Dockerfile = mergeLines(result.Dockerfile, tmpLine)
    89  	result.legacyContext.apps2Files[appName] = append([]string{}, filesToCopy...)
    90  
    91  	return makeItAsApp(appName, filesToCopy, result)
    92  }
    93  
    94  func makeItAsApp(appName string, filesToJudge []string, result *KubefileResult) (version.VersionedApplication, error) {
    95  	appType, err := getApplicationType(filesToJudge)
    96  	if err != nil {
    97  		return nil, fmt.Errorf("failed to judge the application type for %s: %v", appName, err)
    98  	}
    99  
   100  	launchFiles, err := getApplicationFiles(appName, appType, filesToJudge)
   101  	if err != nil {
   102  		return nil, fmt.Errorf("failed to get app (%s)launch files: %v", appName, err)
   103  	}
   104  
   105  	v1App := v1.NewV1Application(
   106  		appName,
   107  		appType,
   108  		launchFiles,
   109  	).(*v1.Application)
   110  	result.Applications[v1App.Name()] = v1App
   111  	return v1App, nil
   112  }
   113  
   114  func downloadRemoteFiles(shadowDir string, files []string) ([]string, error) {
   115  	var (
   116  		downloaded = []string{}
   117  		err        error
   118  	)
   119  
   120  	for _, src := range files {
   121  		var filePath string
   122  		filePath, err = getFileFromURL(src, "", shadowDir)
   123  		if err != nil {
   124  			return nil, errors.Errorf("failed to download file %s, %s", src, err)
   125  		}
   126  		downloaded = append(downloaded, filePath)
   127  	}
   128  	return downloaded, nil
   129  }