github.com/operator-framework/operator-lifecycle-manager@v0.30.0/util/cpb/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/operator-framework/operator-registry/pkg/lib/bundle"
     9  	"github.com/otiai10/copy"
    10  	"github.com/spf13/cobra"
    11  	"gopkg.in/yaml.v2"
    12  )
    13  
    14  func main() {
    15  	if err := rootCmd.Execute(); err != nil {
    16  		fmt.Println(err)
    17  		os.Exit(1)
    18  	}
    19  }
    20  
    21  var rootCmd = &cobra.Command{
    22  	Use:   "cpb [output directory]",
    23  	Short: "Copy bundle content",
    24  	Long: `Copy bundle metadata and manifests into an output directory.
    25  Copy traverses the filesystem from the current directory down
    26  until it finds an annotations.yaml representing the bundle's metadata.
    27  From there, it copies the annotations.yaml file and manifests into the
    28  specified output directory`,
    29  	Run: func(cmd *cobra.Command, args []string) {
    30  		dest := "./bundle"
    31  		if len(args) > 1 {
    32  			// Get the destination position argument
    33  			dest = args[0]
    34  		}
    35  
    36  		if err := copyBundle(dest); err != nil {
    37  			fmt.Println(err)
    38  			os.Exit(1)
    39  		}
    40  	},
    41  }
    42  
    43  func copyBundle(dest string) error {
    44  	// Find the manifest directory
    45  	m, err := getMetadata()
    46  	if err != nil {
    47  		return fmt.Errorf("error finding metadata directory: %s", err)
    48  	}
    49  
    50  	fmt.Printf("%v\n", m)
    51  
    52  	return m.copy(dest)
    53  }
    54  
    55  type metadata struct {
    56  	annotationsFile string
    57  	manifestDir     string
    58  }
    59  
    60  func (m *metadata) copy(dest string) error {
    61  	// Copy the annotations file
    62  	path := filepath.Join(dest, "metadata/annotations.yaml")
    63  	if err := copy.Copy(m.annotationsFile, path); err != nil {
    64  		return err
    65  	}
    66  
    67  	// Copy manifest dir
    68  	path = filepath.Join(dest, "manifests")
    69  	if err := os.MkdirAll(path, os.ModePerm); err != nil {
    70  		return err
    71  	}
    72  	if err := copy.Copy(m.manifestDir, path); err != nil {
    73  		return err
    74  	}
    75  
    76  	return nil
    77  }
    78  
    79  func getMetadata() (m *metadata, err error) {
    80  	// Create default metadata
    81  	m = &metadata{
    82  		annotationsFile: "/metadata/annotations.yaml",
    83  		manifestDir:     "/manifests",
    84  	}
    85  
    86  	// Exclude device filesystems and pseudo filesystems from filesystems looking for metadata
    87  	excludeDir := []string{
    88  		"/dev",
    89  		"/proc",
    90  		"/sys",
    91  	}
    92  
    93  	// Traverse the filesystem looking for metadata
    94  	err = filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
    95  		if err != nil {
    96  			fmt.Printf("prevent panic by handling failure accessing a path %q: %v\n", path, err)
    97  			return nil
    98  		}
    99  		if info.IsDir() {
   100  			absPath, err := filepath.Abs(path)
   101  			if err != nil {
   102  				fmt.Printf("couldn't get the absolute path %q: %v\n", path, err)
   103  				return nil
   104  			}
   105  			for _, v := range excludeDir {
   106  				if v == absPath {
   107  					fmt.Printf("skipping all files in the dir: %+v \n", absPath)
   108  					return filepath.SkipDir
   109  				}
   110  			}
   111  			fmt.Printf("skipping a dir without errors: %+v \n", absPath)
   112  			return nil
   113  		}
   114  		if info.Name() != bundle.AnnotationsFile {
   115  			return nil
   116  		}
   117  		m.annotationsFile = path
   118  
   119  		// Unmarshal metadata
   120  		content, err := os.ReadFile(path)
   121  		if err != nil {
   122  			return fmt.Errorf("couldn't get content of annotations.yaml file: %s", path)
   123  		}
   124  
   125  		annotations := bundle.AnnotationMetadata{}
   126  		if err := yaml.Unmarshal(content, &annotations); err != nil {
   127  			return err
   128  		}
   129  
   130  		if annotations.Annotations == nil {
   131  			return fmt.Errorf("annotations.yaml file unmarshalling failed: %s", path)
   132  		}
   133  
   134  		if manifestDir, ok := annotations.Annotations[bundle.ManifestsLabel]; ok {
   135  			m.manifestDir = manifestDir
   136  		}
   137  
   138  		// Skip the remainder of files in the directory
   139  		return filepath.SkipDir
   140  	})
   141  
   142  	if err != nil {
   143  		m = nil
   144  	}
   145  
   146  	return
   147  }