github.com/containers/podman/v4@v4.9.4/pkg/bindings/README.md (about) 1 # Podman Golang bindings 2 The Podman Go bindings are a set of functions to allow developers to execute Podman operations from within their Go based application. The Go bindings 3 connect to a Podman service which can run locally or on a remote machine. You can perform many operations including pulling and listing images, starting, 4 stopping or inspecting containers. Currently, the Podman repository has bindings available for operations on images, containers, pods, 5 networks and manifests among others. 6 7 ## Quick Start 8 The bindings require that the Podman system service is running for the specified user. This can be done with systemd using the `systemctl` command or manually 9 by calling the service directly. 10 11 ### Starting the service with system 12 The command to start the Podman service differs slightly depending on the user that is running the service. For a rootful service, 13 start the service like this: 14 ``` 15 # systemctl start podman.socket 16 ``` 17 For a non-privileged, aka rootless, user, start the service like this: 18 19 ``` 20 $ systemctl start --user podman.socket 21 ``` 22 23 ### Starting the service manually 24 It can be handy to run the system service manually. Doing so allows you to enable debug messaging. 25 ``` 26 $ podman --log-level=debug system service -t0 27 ``` 28 If you do not provide a specific path for the socket, a default is provided. The location of that socket for 29 rootful connections is `/run/podman/podman.sock` and for rootless it is `/run/user/USERID#/podman/podman.sock`. For more 30 information about the Podman system service, see `man podman-system-service`. 31 32 ### Creating a connection 33 Ensure the [required dependencies](https://podman.io/getting-started/installation#build-and-run-dependencies) are installed, 34 as they will be required to compile a Go program making use of the bindings. 35 36 37 The first step for using the bindings is to create a connection to the socket. As mentioned earlier, the destination 38 of the socket depends on the user who owns it. In this case, a rootful connection is made. 39 40 ``` 41 import ( 42 "context" 43 "fmt" 44 "os" 45 46 "github.com/containers/podman/v4/pkg/bindings" 47 ) 48 49 func main() { 50 conn, err := bindings.NewConnection(context.Background(), "unix:///run/podman/podman.sock") 51 if err != nil { 52 fmt.Println(err) 53 os.Exit(1) 54 } 55 56 } 57 ``` 58 The `conn` variable returned from the `bindings.NewConnection` function can then be used in subsequent function calls 59 to interact with containers. 60 61 ### Examples 62 The following examples build upon the connection example from above. They are all rootful connections as well. 63 64 Note: Optional arguments to the bindings methods are set using With*() methods on *Option structures. 65 Composite types are not duplicated rather the address is used. As such, you should not change an underlying 66 field between initializing the *Option structure and calling the bindings method. 67 68 #### Inspect a container 69 The following example obtains the inspect information for a container named `foorbar` and then prints 70 the container's ID. Note the use of optional inspect options for size. 71 ``` 72 import ( 73 "context" 74 "fmt" 75 "os" 76 77 "github.com/containers/podman/v4/pkg/bindings" 78 "github.com/containers/podman/v4/pkg/bindings/containers" 79 ) 80 81 func main() { 82 conn, err := bindings.NewConnection(context.Background(), "unix:///run/podman/podman.sock") 83 if err != nil { 84 fmt.Println(err) 85 os.Exit(1) 86 } 87 inspectData, err := containers.Inspect(conn, "foobar", new(containers.InspectOptions).WithSize(true)) 88 if err != nil { 89 fmt.Println(err) 90 os.Exit(1) 91 } 92 // Print the container ID 93 fmt.Println(inspectData.ID) 94 } 95 ``` 96 97 #### Pull an image 98 The following example pulls the image `quay.ioo/libpod/alpine_nginx` to the local image store. 99 ``` 100 import ( 101 "context" 102 "fmt" 103 "os" 104 105 "github.com/containers/podman/v4/pkg/bindings" 106 "github.com/containers/podman/v4/pkg/bindings/images" 107 ) 108 109 func main() { 110 conn, err := bindings.NewConnection(context.Background(), "unix:///run/podman/podman.sock") 111 if err != nil { 112 fmt.Println(err) 113 os.Exit(1) 114 } 115 _, err = images.Pull(conn, "quay.io/libpod/alpine_nginx", nil) 116 if err != nil { 117 fmt.Println(err) 118 os.Exit(1) 119 } 120 } 121 122 ``` 123 124 #### Pull an image, create a container, and start the container 125 The following example pulls the `quay.io/libpod/alpine_nginx` image and then creates a container named `foobar` 126 from it. And finally, it starts the container. 127 ``` 128 import ( 129 "context" 130 "fmt" 131 "os" 132 133 "github.com/containers/podman/v4/pkg/bindings" 134 "github.com/containers/podman/v4/pkg/bindings/containers" 135 "github.com/containers/podman/v4/pkg/bindings/images" 136 "github.com/containers/podman/v4/pkg/specgen" 137 ) 138 139 func main() { 140 conn, err := bindings.NewConnection(context.Background(), "unix:///run/podman/podman.sock") 141 if err != nil { 142 fmt.Println(err) 143 os.Exit(1) 144 } 145 _, err = images.Pull(conn, "quay.io/libpod/alpine_nginx", nil) 146 if err != nil { 147 fmt.Println(err) 148 os.Exit(1) 149 } 150 s := specgen.NewSpecGenerator("quay.io/libpod/alpine_nginx", false) 151 s.Name = "foobar" 152 createResponse, err := containers.CreateWithSpec(conn, s, nil) 153 if err != nil { 154 fmt.Println(err) 155 os.Exit(1) 156 } 157 fmt.Println("Container created.") 158 if err := containers.Start(conn, createResponse.ID, nil); err != nil { 159 fmt.Println(err) 160 os.Exit(1) 161 } 162 fmt.Println("Container started.") 163 } 164 ``` 165 166 ## Debugging tips <a name="debugging-tips"></a> 167 168 To debug in a development setup, you can start the Podman system service 169 in debug mode like: 170 171 ```bash 172 $ podman --log-level=debug system service -t 0 173 ``` 174 175 The `--log-level=debug` echoes all the logged requests and is useful to 176 trace the execution path at a finer granularity. A snippet of a sample run looks like: 177 178 ```bash 179 INFO[0000] podman filtering at log level debug 180 DEBU[0000] Called service.PersistentPreRunE(podman --log-level=debug system service -t0) 181 DEBU[0000] Ignoring libpod.conf EventsLogger setting "/home/lsm5/.config/containers/containers.conf". Use "journald" if you want to change this setting and remove libpod.conf files. 182 DEBU[0000] Reading configuration file "/usr/share/containers/containers.conf" 183 DEBU[0000] Merged system config "/usr/share/containers/containers.conf": {Editors note: the remainder of this line was removed due to Jekyll formatting errors.} 184 DEBU[0000] Using conmon: "/usr/bin/conmon" 185 DEBU[0000] Initializing boltdb state at /home/lsm5/.local/share/containers/storage/libpod/bolt_state.db 186 DEBU[0000] Overriding run root "/run/user/1000/containers" with "/run/user/1000" from database 187 DEBU[0000] Using graph driver overlay 188 DEBU[0000] Using graph root /home/lsm5/.local/share/containers/storage 189 DEBU[0000] Using run root /run/user/1000 190 DEBU[0000] Using static dir /home/lsm5/.local/share/containers/storage/libpod 191 DEBU[0000] Using tmp dir /run/user/1000/libpod/tmp 192 DEBU[0000] Using volume path /home/lsm5/.local/share/containers/storage/volumes 193 DEBU[0000] Set libpod namespace to "" 194 DEBU[0000] Not configuring container store 195 DEBU[0000] Initializing event backend file 196 DEBU[0000] using runtime "/usr/bin/runc" 197 DEBU[0000] using runtime "/usr/bin/crun" 198 WARN[0000] Error initializing configured OCI runtime kata: no valid executable found for OCI runtime kata: invalid argument 199 DEBU[0000] using runtime "/usr/bin/crun" 200 INFO[0000] Setting parallel job count to 25 201 INFO[0000] podman filtering at log level debug 202 DEBU[0000] Called service.PersistentPreRunE(podman --log-level=debug system service -t0) 203 DEBU[0000] Ignoring libpod.conf EventsLogger setting "/home/lsm5/.config/containers/containers.conf". Use "journald" if you want to change this setting and remove libpod.conf files. 204 DEBU[0000] Reading configuration file "/usr/share/containers/containers.conf" 205 ``` 206 207 If the Podman system service has been started via systemd socket activation, 208 you can view the logs using journalctl. The logs after a sample run look like: 209 210 ```bash 211 $ journalctl --user --no-pager -u podman.socket 212 -- Reboot -- 213 Jul 22 13:50:40 nagato.nanadai.me systemd[1048]: Listening on Podman API Socket. 214 $ 215 ``` 216 217 ```bash 218 $ journalctl --user --no-pager -u podman.service 219 Jul 22 13:50:53 nagato.nanadai.me systemd[1048]: Starting Podman API Service... 220 Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 38480630a8bdaa3e1a0ebd34c94038591b0d7ad994b37be5b4f2072bb6ef0879: error acquiring lock 0 for volume 38480630a8bdaa3e1a0ebd34c94038591b0d7ad994b37be5b4f2072bb6ef0879: file exists" 221 Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 47d410af4d762a0cc456a89e58f759937146fa3be32b5e95a698a1d4069f4024: error acquiring lock 0 for volume 47d410af4d762a0cc456a89e58f759937146fa3be32b5e95a698a1d4069f4024: file exists" 222 Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 86e73f082e344dad38c8792fb86b2017c4f133f2a8db87f239d1d28a78cf0868: error acquiring lock 0 for volume 86e73f082e344dad38c8792fb86b2017c4f133f2a8db87f239d1d28a78cf0868: file exists" 223 Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume 9a16ea764be490a5563e384d9074ab0495e4d9119be380c664037d6cf1215631: error acquiring lock 0 for volume 9a16ea764be490a5563e384d9074ab0495e4d9119be380c664037d6cf1215631: file exists" 224 Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume bfd6b2a97217f8655add13e0ad3f6b8e1c79bc1519b7a1e15361a107ccf57fc0: error acquiring lock 0 for volume bfd6b2a97217f8655add13e0ad3f6b8e1c79bc1519b7a1e15361a107ccf57fc0: file exists" 225 Jul 22 13:50:54 nagato.nanadai.me podman[1527]: time="2020-07-22T13:50:54-04:00" level=error msg="Error refreshing volume f9b9f630982452ebcbed24bd229b142fbeecd5d4c85791fca440b21d56fef563: error acquiring lock 0 for volume f9b9f630982452ebcbed24bd229b142fbeecd5d4c85791fca440b21d56fef563: file exists" 226 Jul 22 13:50:54 nagato.nanadai.me podman[1527]: Trying to pull registry.fedoraproject.org/fedora:latest... 227 Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Getting image source signatures 228 Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Copying blob sha256:dd9f43919ba05f05d4f783c31e83e5e776c4f5d29dd72b9ec5056b9576c10053 229 Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Copying config sha256:00ff39a8bf19f810a7e641f7eb3ddc47635913a19c4996debd91fafb6b379069 230 Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Writing manifest to image destination 231 Jul 22 13:50:55 nagato.nanadai.me podman[1527]: Storing signatures 232 Jul 22 13:50:55 nagato.nanadai.me systemd[1048]: podman.service: unit configures an IP firewall, but not running as root. 233 Jul 22 13:50:55 nagato.nanadai.me systemd[1048]: (This warning is only shown for the first unit using IP firewalling.) 234 Jul 22 13:51:15 nagato.nanadai.me systemd[1048]: podman.service: Succeeded. 235 Jul 22 13:51:15 nagato.nanadai.me systemd[1048]: Finished Podman API Service. 236 Jul 22 13:51:15 nagato.nanadai.me systemd[1048]: podman.service: Consumed 1.339s CPU time. 237 $ 238 ``` 239 240 You can also verify that the information being passed back and forth is correct by putting 241 with a tool like `socat`, which can dump what the socket is seeing.