mirror of
				https://github.com/linuxkit/linuxkit.git
				synced 2025-10-31 21:45:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			96 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"flag"
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 
 | |
| 	log "github.com/sirupsen/logrus"
 | |
| 	"golang.org/x/sys/unix"
 | |
| )
 | |
| 
 | |
| func volumeInitCmd(ctx context.Context) int {
 | |
| 	invoked := filepath.Base(os.Args[0])
 | |
| 	flags := flag.NewFlagSet("volume", flag.ExitOnError)
 | |
| 	flags.Usage = func() {
 | |
| 		fmt.Printf("USAGE: %s volume\n\n", invoked)
 | |
| 		fmt.Printf("Options:\n")
 | |
| 		flags.PrintDefaults()
 | |
| 	}
 | |
| 
 | |
| 	path := flags.String("path", defaultVolumesPath, "Path to volume configs")
 | |
| 
 | |
| 	// Set up volumes
 | |
| 	vols, err := os.ReadDir(*path)
 | |
| 	// just skip if there is an error, eg no such path
 | |
| 	if err != nil {
 | |
| 		return 1
 | |
| 	}
 | |
| 	// go through each volume, ensure that the volPath/merged exists as a directory,
 | |
| 	// and is one of:
 | |
| 	// - read-only: i.e. no tmp exists, merged bindmounted to lower
 | |
| 	// - read-write: i.e. tmp exists, overlayfs lower/upper/merged
 | |
| 	for _, vol := range vols {
 | |
| 		subs, err := os.ReadDir(filepath.Join(*path, vol.Name()))
 | |
| 		if err != nil {
 | |
| 			log.WithError(err).Errorf("Error reading volume %s", vol.Name())
 | |
| 			return 1
 | |
| 		}
 | |
| 		var hasLower, hasMerged, readWrite bool
 | |
| 		for _, sub := range subs {
 | |
| 			switch sub.Name() {
 | |
| 			case "lower":
 | |
| 				hasLower = true
 | |
| 			case "tmp":
 | |
| 				readWrite = true
 | |
| 			case "merged":
 | |
| 				hasMerged = true
 | |
| 			}
 | |
| 		}
 | |
| 		if !hasMerged {
 | |
| 			log.Errorf("Volume %s does not have a merged directory", vol.Name())
 | |
| 			return 1
 | |
| 		}
 | |
| 		if !hasLower {
 | |
| 			log.Errorf("Volume %s does not have a lower directory", vol.Name())
 | |
| 			return 1
 | |
| 		}
 | |
| 		lowerDir := filepath.Join(*path, vol.Name(), "lower")
 | |
| 		mergedDir := filepath.Join(*path, vol.Name(), "merged")
 | |
| 		// need a tmpfs to create the workdir and upper
 | |
| 		tmpDir := filepath.Join(*path, vol.Name(), "tmp")
 | |
| 		if err := unix.Mount("tmpfs", tmpDir, "tmpfs", unix.MS_RELATIME, ""); err != nil {
 | |
| 			log.WithError(err).Errorf("Error creating tmpDir for volume %s", vol.Name())
 | |
| 			return 1
 | |
| 		}
 | |
| 		workDir := filepath.Join(tmpDir, "work")
 | |
| 		upperDir := filepath.Join(tmpDir, "upper")
 | |
| 		if err := os.Mkdir(upperDir, 0755); err != nil {
 | |
| 			log.WithError(err).Errorf("Error creating upper dir for volume %s", vol.Name())
 | |
| 			return 1
 | |
| 		}
 | |
| 		if err := os.Mkdir(workDir, 0755); err != nil {
 | |
| 			log.WithError(err).Errorf("Error creating work dir for volume %s", vol.Name())
 | |
| 			return 1
 | |
| 		}
 | |
| 		// and let's mount the actual dir
 | |
| 		mountOps := []string{fmt.Sprintf("lowerdir=%s", lowerDir), fmt.Sprintf("upperdir=%s", upperDir), fmt.Sprintf("workdir=%s", workDir)}
 | |
| 
 | |
| 		if !readWrite {
 | |
| 			log.Infof("Volume %s is read-only", vol.Name())
 | |
| 			mountOps = append(mountOps, "ro")
 | |
| 		} else {
 | |
| 			log.Infof("Volume %s is read-write", vol.Name())
 | |
| 		}
 | |
| 		data := strings.Join(mountOps, ",")
 | |
| 		if err := unix.Mount("overlay", mergedDir, "overlay", unix.MS_RELATIME, data); err != nil {
 | |
| 			log.WithError(err).Errorf("Error overlay-mounting volume %s", vol.Name())
 | |
| 			return 1
 | |
| 		}
 | |
| 	}
 | |
| 	return 0
 | |
| }
 |