github.com/rawahars/moby@v24.0.4+incompatible/contrib/docker-device-tool/device_tool.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package main
     5  
     6  import (
     7  	"flag"
     8  	"fmt"
     9  	"os"
    10  	"path"
    11  	"sort"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"github.com/docker/docker/daemon/graphdriver/devmapper"
    16  	"github.com/docker/docker/pkg/devicemapper"
    17  	"github.com/docker/docker/pkg/idtools"
    18  	"github.com/sirupsen/logrus"
    19  )
    20  
    21  func usage() {
    22  	fmt.Fprintf(os.Stderr, "Usage: %s <flags>  [status] | [list] | [device id]  | [resize new-pool-size] | [snap new-id base-id] | [remove id] | [mount id mountpoint]\n", os.Args[0])
    23  	flag.PrintDefaults()
    24  	os.Exit(1)
    25  }
    26  
    27  func byteSizeFromString(arg string) (int64, error) {
    28  	digits := ""
    29  	rest := ""
    30  	last := strings.LastIndexAny(arg, "0123456789")
    31  	if last >= 0 {
    32  		digits = arg[:last+1]
    33  		rest = arg[last+1:]
    34  	}
    35  
    36  	val, err := strconv.ParseInt(digits, 10, 64)
    37  	if err != nil {
    38  		return val, err
    39  	}
    40  
    41  	rest = strings.ToLower(strings.TrimSpace(rest))
    42  
    43  	var multiplier int64
    44  	switch rest {
    45  	case "":
    46  		multiplier = 1
    47  	case "k", "kb":
    48  		multiplier = 1024
    49  	case "m", "mb":
    50  		multiplier = 1024 * 1024
    51  	case "g", "gb":
    52  		multiplier = 1024 * 1024 * 1024
    53  	case "t", "tb":
    54  		multiplier = 1024 * 1024 * 1024 * 1024
    55  	default:
    56  		return 0, fmt.Errorf("Unknown size unit: %s", rest)
    57  	}
    58  
    59  	return val * multiplier, nil
    60  }
    61  
    62  func main() {
    63  	root := flag.String("r", "/var/lib/docker", "Docker root dir")
    64  	flDebug := flag.Bool("D", false, "Debug mode")
    65  
    66  	flag.Parse()
    67  
    68  	if *flDebug {
    69  		os.Setenv("DEBUG", "1")
    70  		logrus.SetLevel(logrus.DebugLevel)
    71  	}
    72  
    73  	if flag.NArg() < 1 {
    74  		usage()
    75  	}
    76  
    77  	args := flag.Args()
    78  
    79  	home := path.Join(*root, "devicemapper")
    80  	devices, err := devmapper.NewDeviceSet(home, false, nil, idtools.IdentityMapping{})
    81  	if err != nil {
    82  		fmt.Println("Can't initialize device mapper: ", err)
    83  		os.Exit(1)
    84  	}
    85  
    86  	switch args[0] {
    87  	case "status":
    88  		status := devices.Status()
    89  		fmt.Printf("Pool name: %s\n", status.PoolName)
    90  		fmt.Printf("Data Loopback file: %s\n", status.DataLoopback)
    91  		fmt.Printf("Metadata Loopback file: %s\n", status.MetadataLoopback)
    92  		fmt.Printf("Sector size: %d\n", status.SectorSize)
    93  		fmt.Printf("Data use: %d of %d (%.1f %%)\n", status.Data.Used, status.Data.Total, 100.0*float64(status.Data.Used)/float64(status.Data.Total))
    94  		fmt.Printf("Metadata use: %d of %d (%.1f %%)\n", status.Metadata.Used, status.Metadata.Total, 100.0*float64(status.Metadata.Used)/float64(status.Metadata.Total))
    95  	case "list":
    96  		ids := devices.List()
    97  		sort.Strings(ids)
    98  		for _, id := range ids {
    99  			fmt.Println(id)
   100  		}
   101  	case "device":
   102  		if flag.NArg() < 2 {
   103  			usage()
   104  		}
   105  		status, err := devices.GetDeviceStatus(args[1])
   106  		if err != nil {
   107  			fmt.Println("Can't get device info: ", err)
   108  			os.Exit(1)
   109  		}
   110  		fmt.Printf("Id: %d\n", status.DeviceID)
   111  		fmt.Printf("Size: %d\n", status.Size)
   112  		fmt.Printf("Transaction Id: %d\n", status.TransactionID)
   113  		fmt.Printf("Size in Sectors: %d\n", status.SizeInSectors)
   114  		fmt.Printf("Mapped Sectors: %d\n", status.MappedSectors)
   115  		fmt.Printf("Highest Mapped Sector: %d\n", status.HighestMappedSector)
   116  	case "resize":
   117  		if flag.NArg() < 2 {
   118  			usage()
   119  		}
   120  
   121  		size, err := byteSizeFromString(args[1])
   122  		if err != nil {
   123  			fmt.Println("Invalid size: ", err)
   124  			os.Exit(1)
   125  		}
   126  
   127  		err = devices.ResizePool(size)
   128  		if err != nil {
   129  			fmt.Println("Error resizing pool: ", err)
   130  			os.Exit(1)
   131  		}
   132  
   133  	case "snap":
   134  		if flag.NArg() < 3 {
   135  			usage()
   136  		}
   137  
   138  		err := devices.AddDevice(args[1], args[2], nil)
   139  		if err != nil {
   140  			fmt.Println("Can't create snap device: ", err)
   141  			os.Exit(1)
   142  		}
   143  	case "remove":
   144  		if flag.NArg() < 2 {
   145  			usage()
   146  		}
   147  
   148  		err := devicemapper.RemoveDevice(args[1])
   149  		if err != nil {
   150  			fmt.Println("Can't remove device: ", err)
   151  			os.Exit(1)
   152  		}
   153  	case "mount":
   154  		if flag.NArg() < 3 {
   155  			usage()
   156  		}
   157  
   158  		err := devices.MountDevice(args[1], args[2], "")
   159  		if err != nil {
   160  			fmt.Println("Can't mount device: ", err)
   161  			os.Exit(1)
   162  		}
   163  	default:
   164  		fmt.Printf("Unknown command %s\n", args[0])
   165  		usage()
   166  
   167  		os.Exit(1)
   168  	}
   169  }