Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add runtime state configuration and structs #87

Merged
merged 1 commit into from
Sep 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ type MountPoint struct {
// Path specifies the path of the mount. The path and child directories MUST exist, a runtime MUST NOT create directories automatically to a mount point.
Path string `json:"path"`
}

// State holds information about the runtime state of the container.
type State struct {
// Version is the version of the specification that is supported.
Version string `json:"version"`
// ID is the container ID
ID string `json:"id"`
// Pid is the process id for the container's main process.
Pid int `json:"pid"`
// Root is the path to the container's bundle directory.
Root string `json:"root"`
}
29 changes: 29 additions & 0 deletions runtime.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Runtime and Lifecycle

## State

The runtime state for a container is persisted on disk so that external tools can consume and act on this information.
The runtime state is stored in a JSON encoded file.
It is recommended that this file is stored in a temporary filesystem so that it can be removed on a system reboot.
On Linux based systems the state information should be stored in `/run/oci/containers`.
The directory structure for a container is `/run/oci/containers/<containerID>/state.json`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the meeting, my understanding was that we wanted a flat /run/oci/{containerID}/state.json namespace, with internal-to-the-state content for figuring out the semantics of the state content. If the state.json requires a version field that clarifies the associated spec (e.g. my suggestion here), there would be no need for the containers/ path to namespace different types of container specs.

By providing a default location that container state is stored external applications can find all containers running on a system.

* **version** (string) Version of the OCI specification used when creating the container.
* **id** (string) ID is the container's ID.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id is a bit under specified; are there any restrictions on the format of the string? what is the uniqueness domain?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about all lowercase alphabets and digits?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Wed, Aug 05, 2015 at 09:19:02AM -0700, Mrunal Patel wrote:

+* id (string) ID is the container's ID.

How about all lowercase alphabets and digits?

That sounds good to me, although we might want to allow hyphens for
folks who want to use UUIDs. And currently runC defaults to the
bundle's directory name, so we'd need to figure out how we wanted to
map other characters into the valid character set.

Do we want to add requirements for the uniqueness domain? Unique to
the host seems like a minimum, but we can require universal uniqueness
(e.g. “container IDs must be UUIDs 1”) or leave that up to the
implementation. I'd rather leave it up to the implementation, since
as long as UUIDs are valid container identifiers, runtime callers
that want universal uniqueness are free to use them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add a comment that the reason we have an ID is because the hooks only get an open fd to this json document so they won't know the unique ID which may be useful for removal, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to note that containerID MUST match the containerID subdirectory field.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Wed, Aug 26, 2015 at 10:12:52AM -0700, Brandon Philips wrote:

+* id (string) ID is the container's ID.

We need to add a comment that the reason we have an ID is because
the hooks only get an open fd to this json document so they won't
know the unique ID which may be useful for removal, etc.

I wasn't clear on how it would be useful for removal. Everyone got on
board when someone mentioned network teardown, but the connection
between that and the container ID wasn't clear to me. Not that we
have to be completely specific when motivating this entry. I'm just
pointing out that if we want to explain why we need the container ID
in a post-stop hook, we might want to provide more detail than we had
in today's meeting.

* **pid** (int) Pid is the ID of the main process within the container.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe clarify the host's process namespace? For example:

pid (int) The ID of the application process in the host's process namespace.

assuming we land something like #107 to get a definition for “application”. Although this somewhat conflates the initial process and the whole tree descending from that process under application. And I'm not sure what happens if there are fork/exec calls to split off new trees and the container isn't using process namespacing.

* **root** (string) Root is the path to the container's bundle directory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of today's meeting was that we did need host-side path to the container's root filesystem here. Folks were motivating this entry for mounting additional host-side content into the container's filesystem. I don't see how the bundle root would help much there. Maybe bundle-root → config.jsonroot.path? But that assumes that the container wasn't launched with an alternate config, that the config hasn't been tweaked since launch, …. It seems better to just point folks directly at the container's root filesystem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I don't see why we'd need root at all, because it's easy to find the path to all container-mounted filesystems by looking in /proc/{pid}/mountinfo, and I don't see why the root filesystem would deserve special treatment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I don't see why we'd need root at all, because it's easy to find
the path to all container-mounted filesystems by looking in
/proc/{pid}/mountinfo, and I don't see why the root filesystem would
deserve special treatment.

That is assuming that root has been mounted?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vbatts Can we get the host path to the bundle root from /proc/{application pid}/mountinfo? I think that is the point of this field.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crosbymichael can you clarify if this is the root of the bundle or the rootfs of the bundle? We should probably call it bundlepath or rootfs or something to clarify.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philips sorry. formatting got jacked up. That was my point in replying to @wking

Deriving the root of a container from /proc/pid/mountinfo is not guaranteed. So this field is needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vbatts ack, ok, all we need now is for @crosbymichael to clarify where this actually points in the bundle

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Sat, Aug 29, 2015 at 09:36:51AM -0700, Vincent Batts wrote:

Deriving the root of a container from /proc/pid/mountinfo is not
guaranteed. So this field is needed.

You mentioned root needing to be mounted for this 1, but I'm not
clear on what that means. In what situation would the container's
root not be mounted? For example, here's a container with a mount
namespace:

$ cat /proc/6468/mountinfo
67 41 0:18 /home/…/oci-gentoo-minimal/rootfs / ro,noatime - btrfs /dev/sda4 rw,ssd,space_cache

showing that the container's root is at the host's
/home/…/oci-gentoo-minimal/rootfs.

And here's a container without a mount namespace:

$ cat /proc/6304/mountinfo
18 0 0:18 / / rw,noatime - btrfs /dev/sda4 rw,ssd,space_cache

showing that the container's root is the same as my host's root.
Although without a mount namespace, I don't know what the
config.json's ‘root’ setting does (this is similar to, but not the
same as my not thinking that we should require a rootfs directory in
the bundle 2).


The ID is provided in the state because hooks will be executed with the state as the payload.
This allows the hook to perform clean and teardown logic after the runtime destroys its own state.

The root directory to the bundle is provided in the state so that consumers can find the container's configuration and rootfs where it is located on the host's filesystem.

*Example*

```json
{
"id": "oci-container",
"pid": 4422,
"root": "/containers/redis"
}
```

## Lifecycle

### Create
Expand Down
3 changes: 3 additions & 0 deletions runtime_config_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package specs

import "os"

// LinuxStateDirectory holds the container's state information
const LinuxStateDirectory = "/run/oci/containers"

// LinuxRuntimeSpec is the full specification for linux containers.
type LinuxRuntimeSpec struct {
RuntimeSpec
Expand Down