github.com/mattmoor/mink@v1.3.1/pkg/bundles/kontext/expand.go (about)

     1  /*
     2  Copyright 2020 The Knative 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 kontext
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  	"log"
    23  	"os"
    24  	"path/filepath"
    25  
    26  	"knative.dev/pkg/pool"
    27  )
    28  
    29  const (
    30  	// StoragePath is where in the container image the files are placed.
    31  	StoragePath = "/var/run/kontext"
    32  )
    33  
    34  func copy(src, dest string) error {
    35  	from, err := os.Open(src)
    36  	if err != nil {
    37  		return err
    38  	}
    39  	defer from.Close()
    40  
    41  	to, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE, os.ModePerm)
    42  	if err != nil {
    43  		return err
    44  	}
    45  	defer to.Close()
    46  
    47  	_, err = io.Copy(to, from)
    48  	return err
    49  }
    50  
    51  func expand(ctx context.Context, base string) error {
    52  	targetPath, err := os.Getwd()
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	eg, ctx := pool.NewWithContext(ctx, 100 /* workers */, 100 /* capacity */)
    58  	if err := filepath.Walk(base, func(path string, info os.FileInfo, err error) error {
    59  		if err != nil {
    60  			return err
    61  		}
    62  
    63  		if path == base {
    64  			return nil
    65  		}
    66  
    67  		// Add each file to the backlog.
    68  		eg.Go(func() error {
    69  			// If the context is canceled, then bail out early.
    70  			select {
    71  			case <-ctx.Done():
    72  				return ctx.Err()
    73  			default:
    74  			}
    75  
    76  			relativePath := path[len(base)+1:]
    77  			target := filepath.Join(targetPath, relativePath)
    78  
    79  			if info.IsDir() {
    80  				return os.MkdirAll(target, os.ModePerm)
    81  			}
    82  			if !info.Mode().IsRegular() {
    83  				log.Printf("Skipping irregular file: %q", relativePath)
    84  				return nil
    85  			}
    86  			if err := os.MkdirAll(filepath.Dir(target), os.ModePerm); err != nil {
    87  				return err
    88  			}
    89  			return copy(path, target)
    90  		})
    91  
    92  		return nil
    93  	}); err != nil {
    94  		return err
    95  	}
    96  
    97  	// Wait for the work to be done.
    98  	return eg.Wait()
    99  }
   100  
   101  // Expand recursively copies the current working directory into StoragePath.
   102  func Expand(ctx context.Context) error {
   103  	return expand(ctx, StoragePath)
   104  }