1package main 2 3import ( 4 "bufio" 5 "compress/gzip" 6 "io" 7 "os" 8 "path/filepath" 9 10 "github.com/Microsoft/go-winio" 11 "github.com/Microsoft/hcsshim/internal/appargs" 12 "github.com/Microsoft/hcsshim/internal/ociwclayer" 13 "github.com/urfave/cli" 14) 15 16var importCommand = cli.Command{ 17 Name: "import", 18 Usage: "imports a layer from a tar file", 19 Flags: []cli.Flag{ 20 cli.StringSliceFlag{ 21 Name: "layer, l", 22 Usage: "paths to the read-only parent layers", 23 }, 24 cli.StringFlag{ 25 Name: "input, i", 26 Usage: "input layer tar (defaults to stdin)", 27 }, 28 }, 29 ArgsUsage: "<layer path>", 30 Before: appargs.Validate(appargs.NonEmptyString), 31 Action: func(context *cli.Context) (err error) { 32 path, err := filepath.Abs(context.Args().First()) 33 if err != nil { 34 return err 35 } 36 37 layers, err := normalizeLayers(context.StringSlice("layer"), false) 38 if err != nil { 39 return err 40 } 41 42 fp := context.String("input") 43 f := os.Stdin 44 if fp != "" { 45 f, err = os.Open(fp) 46 if err != nil { 47 return err 48 } 49 defer f.Close() 50 } 51 r, err := addDecompressor(f) 52 if err != nil { 53 return err 54 } 55 err = winio.EnableProcessPrivileges([]string{winio.SeBackupPrivilege, winio.SeRestorePrivilege}) 56 if err != nil { 57 return err 58 } 59 _, err = ociwclayer.ImportLayer(r, path, layers) 60 return err 61 }, 62} 63 64func addDecompressor(r io.Reader) (io.Reader, error) { 65 b := bufio.NewReader(r) 66 hdr, err := b.Peek(3) 67 if err != nil { 68 return nil, err 69 } 70 if hdr[0] == 0x1f && hdr[1] == 0x8b && hdr[2] == 8 { 71 return gzip.NewReader(b) 72 } 73 return b, nil 74} 75