github.com/circular-dark/docker@v1.7.0/contrib/docker-device-tool/device_tool.go (about)

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