github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/contrib/docker-device-tool/device_tool.go (about)

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