github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/build/buildinstruction/utils.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 buildinstruction 16 17 import ( 18 "context" 19 "fmt" 20 "os" 21 "path/filepath" 22 "strings" 23 24 "github.com/alibaba/sealer/utils/collector" 25 26 fsutil "github.com/tonistiigi/fsutil/copy" 27 28 "github.com/alibaba/sealer/pkg/image" 29 "github.com/alibaba/sealer/pkg/image/cache" 30 "github.com/alibaba/sealer/utils" 31 32 "github.com/opencontainers/go-digest" 33 34 "github.com/alibaba/sealer/common" 35 "github.com/alibaba/sealer/logger" 36 v1 "github.com/alibaba/sealer/types/api/v1" 37 "github.com/alibaba/sealer/utils/archive" 38 ) 39 40 func tryCache(parentID cache.ChainID, 41 layer v1.Layer, 42 cacheService cache.Service, 43 prober image.Prober, 44 srcFilesDgst digest.Digest) (hitCache bool, layerID digest.Digest, chainID cache.ChainID) { 45 var err error 46 cacheLayer := cacheService.NewCacheLayer(layer, srcFilesDgst) 47 cacheLayerID, err := prober.Probe(parentID.String(), &cacheLayer) 48 if err != nil { 49 logger.Debug("failed to probe cache for %+v, err: %s", layer, err) 50 return false, "", "" 51 } 52 // cache hit 53 logger.Info("---> Using cache %v", cacheLayerID) 54 //layer.ID = cacheLayerID 55 cID, err := cacheLayer.ChainID(parentID) 56 if err != nil { 57 return false, "", "" 58 } 59 return true, cacheLayerID, cID 60 } 61 62 func GenerateSourceFilesDigest(root, src string) (digest.Digest, error) { 63 m, err := fsutil.ResolveWildcards(root, src, true) 64 if err != nil { 65 return "", err 66 } 67 68 // wrong wildcards: no such file or directory 69 if len(m) == 0 { 70 return "", fmt.Errorf("%s not found", src) 71 } 72 73 if len(m) == 1 { 74 return generateDigest(filepath.Join(root, src)) 75 } 76 77 tmp, err := utils.MkTmpdir() 78 if err != nil { 79 return "", fmt.Errorf("failed to create tmp dir %s:%v", tmp, err) 80 } 81 82 defer func() { 83 if err = os.RemoveAll(tmp); err != nil { 84 logger.Warn(err) 85 } 86 }() 87 88 xattrErrorHandler := func(dst, src, key string, err error) error { 89 logger.Warn(err) 90 return nil 91 } 92 opt := []fsutil.Opt{ 93 fsutil.WithXAttrErrorHandler(xattrErrorHandler), 94 } 95 96 for _, s := range m { 97 if err := fsutil.Copy(context.TODO(), root, s, tmp, filepath.Base(s), opt...); err != nil { 98 return "", err 99 } 100 } 101 102 return generateDigest(tmp) 103 } 104 105 func generateDigest(path string) (digest.Digest, error) { 106 layerDgst, _, err := archive.TarCanonicalDigest(path) 107 if err != nil { 108 return "", err 109 } 110 return layerDgst, nil 111 } 112 113 // GetBaseLayersPath used in build stage, where the image still has from layer 114 func GetBaseLayersPath(layers []v1.Layer) (res []string) { 115 for _, layer := range layers { 116 if layer.ID != "" { 117 res = append(res, filepath.Join(common.DefaultLayerDir, layer.ID.Hex())) 118 } 119 } 120 return res 121 } 122 123 func ParseCopyLayerContent(layerValue string) (src, dst string) { 124 dst = strings.Fields(layerValue)[1] 125 for _, p := range []string{"./", "/"} { 126 dst = strings.TrimPrefix(dst, p) 127 } 128 dst = strings.TrimSuffix(dst, "/") 129 src = strings.Fields(layerValue)[0] 130 return 131 } 132 133 func isRemoteSource(src string) bool { 134 if collector.IsURL(src) || collector.IsGitURL(src) { 135 return true 136 } 137 return false 138 }