|
1 | | -// Package image provides libraries and commands to interact with containers images. |
| 1 | +// The package image provides libraries and commands to interact with container images. |
2 | 2 | // |
3 | 3 | // package main |
4 | 4 | // |
5 | 5 | // import ( |
6 | | -// "context" |
7 | | -// "fmt" |
| 6 | +// "context" |
| 7 | +// "fmt" |
8 | 8 | // |
9 | | -// "github.com/containers/image/v5/docker" |
| 9 | +// "github.com/containers/image/v5/docker" |
10 | 10 | // ) |
11 | 11 | // |
12 | 12 | // func main() { |
13 | | -// ref, err := docker.ParseReference("//fedora") |
14 | | -// if err != nil { |
15 | | -// panic(err) |
16 | | -// } |
17 | | -// ctx := context.Background() |
18 | | -// img, err := ref.NewImage(ctx, nil) |
19 | | -// if err != nil { |
20 | | -// panic(err) |
21 | | -// } |
22 | | -// defer img.Close() |
23 | | -// b, _, err := img.Manifest(ctx) |
24 | | -// if err != nil { |
25 | | -// panic(err) |
26 | | -// } |
27 | | -// fmt.Printf("%s", string(b)) |
| 13 | +// ref, err := docker.ParseReference("//fedora") |
| 14 | +// if err != nil { |
| 15 | +// panic(err) |
| 16 | +// } |
| 17 | +// ctx := context.Background() |
| 18 | +// img, err := ref.NewImage(ctx, nil) |
| 19 | +// if err != nil { |
| 20 | +// panic(err) |
| 21 | +// } |
| 22 | +// defer img.Close() |
| 23 | +// b, _, err := img.Manifest(ctx) |
| 24 | +// if err != nil { |
| 25 | +// panic(err) |
| 26 | +// } |
| 27 | +// fmt.Printf("%s", string(b)) |
28 | 28 | // } |
29 | 29 | // |
30 | 30 | // |
| 31 | +// ## Notes on running in rootless mode |
| 32 | +// |
| 33 | +// If your application needs to access a containers/storage store in rootless |
| 34 | +// mode, then the following additional steps have to be performed at start-up of |
| 35 | +// your application: |
| 36 | +// |
| 37 | +// package main |
| 38 | +// |
| 39 | +// import ( |
| 40 | +// "github.com/containers/storage/pkg/reexec" |
| 41 | +// "github.com/syndtr/gocapability/capability" |
| 42 | +// "github.com/containers/storage/pkg/unshare" |
| 43 | +// ) |
| 44 | +// |
| 45 | +// var neededCapabilities = []capability.Cap{ |
| 46 | +// capability.CAP_CHOWN, |
| 47 | +// capability.CAP_DAC_OVERRIDE, |
| 48 | +// capability.CAP_FOWNER, |
| 49 | +// capability.CAP_FSETID, |
| 50 | +// capability.CAP_MKNOD, |
| 51 | +// capability.CAP_SETFCAP, |
| 52 | +// } |
| 53 | +// |
| 54 | +// func main() { |
| 55 | +// reexec.Init() |
| 56 | +// |
| 57 | +// capabilities, err := capability.NewPid(0) |
| 58 | +// if err != nil { |
| 59 | +// panic(err) |
| 60 | +// } |
| 61 | +// for _, cap := range neededCapabilities { |
| 62 | +// if !capabilities.Get(capability.EFFECTIVE, cap) { |
| 63 | +// // We miss a capability we need, create a user namespaces |
| 64 | +// unshare.MaybeReexecUsingUserNamespace(true) |
| 65 | +// } |
| 66 | +// } |
| 67 | +// // rest of your code follows here |
| 68 | +// } |
| 69 | +// |
31 | 70 | // TODO(runcom) |
32 | 71 | package image |
0 commit comments