{"action":"created","comment":{"url":"https://api.github.com/repos/opencontainers/runc/pulls/comments/49776988","id":49776988,"diff_hunk":"@@ -56,166 +54,246 @@ int setns(int fd, int nstype)\n #endif\n #endif\n \n-static int clone_parent(jmp_buf * env) __attribute__ ((noinline));\n-static int clone_parent(jmp_buf * env)\n+static int clone_parent(jmp_buf * env, int flags) __attribute__ ((noinline));\n+static int clone_parent(jmp_buf * env, int flags)\n {\n \tstruct clone_arg ca;\n \tint child;\n \n \tca.env = env;\n-\tchild = clone(child_func, ca.stack_ptr, CLONE_PARENT | SIGCHLD, &ca);\n-\n+\tchild =\n+\t    clone(child_func, ca.stack_ptr, CLONE_PARENT | SIGCHLD | flags,\n+\t\t  &ca);\n \treturn child;\n }\n \n+// get init pipe from the parent. It's used to read bootstrap data, and to\n+// write pid to after nsexec finishes setting up the environment.\n+static int get_init_pipe()\n+{\n+\tchar buf[PATH_MAX], *initpipe;\n+\tint pipenum = -1;\n+\n+\tinitpipe = getenv(\"_LIBCONTAINER_INITPIPE\");\n+\tif (initpipe == NULL) {\n+\t\treturn -1;\n+\t}\n+\n+\tpipenum = atoi(initpipe);\n+\tsnprintf(buf, sizeof(buf), \"%d\", pipenum);\n+\tif (strcmp(initpipe, buf)) {\n+\t\tpr_perror(\"Unable to parse _LIBCONTAINER_INITPIPE\");\n+\t\texit(1);\n+\t}\n+\n+\treturn pipenum;\n+}\n+\n+// num_namespaces returns the number of additional namespaces to setns. The\n+// argument is a comma-separated string of namespace paths.\n+static int num_namespaces(char *nspaths)\n+{\n+\tint size = 0, i = 0;\n+\n+\tfor (i = 0; nspaths[i]; i++) {\n+\t\tif (nspaths[i] == ',') {\n+\t\t\tsize += 1;\n+\t\t}\n+\t}\n+\n+\treturn size + 1;\n+}\n+\n static uint32_t readint32(char *buf)\n {\n \treturn *(uint32_t *) buf;\n }\n \n+static uint8_t readint8(char *buf)\n+{\n+\treturn *(uint8_t *) buf;\n+}\n+\n+static void writedata(int fd, char *data, int start, int len)\n+{\n+\tint written = 0;\n+\twhile (written < len) {\n+\t\tsize_t nbyte, i;\n+\t\tif ((len - written) < 1024) {\n+\t\t\tnbyte = len - written;\n+\t\t} else {\n+\t\t\tnbyte = 1024;\n+\t\t}\n+\t\ti = write(fd, data + start + written, nbyte);\n+\t\tif (i == -1) {\n+\t\t\tpr_perror(\"failed to write data to %d\", fd);\n+\t\t\texit(1);\n+\t\t}\n+\t\twritten += i;\n+\t}\n+}\n+\n // list of known message types we want to send to bootstrap program\n // These are defined in libcontainer/message_linux.go\n-#define INIT_MSG 62000\n-#define PID_ATTR 27281\n-#define CONSOLE_PATH_ATTR 27282\n+#define INIT_MSG            62000\n+#define CLONE_FLAGS_ATTR    27281\n+#define CONSOLE_PATH_ATTR   27282\n+#define NS_PATHS_ATTR       27283\n+#define UIDMAP_ATTR         27284\n+#define GIDMAP_ATTR         27285\n+#define SETGROUP_ATTR       27286\n \n void nsexec()\n {\n-\tchar *namespaces[] = { \"ipc\", \"uts\", \"net\", \"pid\", \"mnt\", \"user\" };\n-\tconst int num = sizeof(namespaces) / sizeof(char *);\n \tjmp_buf env;\n-\tchar buf[PATH_MAX], *val;\n-\tint i, tfd, self_tfd, child, n, len, pipenum, consolefd = -1;\n-\tpid_t pid = 0;\n+\tint pipenum;\n \n-\t// if we dont have INITTYPE or this is the init process, skip the bootstrap process\n-\tval = getenv(\"_LIBCONTAINER_INITTYPE\");\n-\tif (val == NULL || strcmp(val, \"standard\") == 0) {\n+\t// if we dont have init pipe, then just return to the parent\n+\tpipenum = get_init_pipe();\n+\tif (pipenum == -1) {\n \t\treturn;\n \t}\n-\tif (strcmp(val, \"setns\") != 0) {\n-\t\tpr_perror(\"Invalid inittype %s\", val);\n-\t\texit(1);\n-\t}\n-\n-\tval = getenv(\"_LIBCONTAINER_INITPIPE\");\n-\tif (val == NULL) {\n-\t\tpr_perror(\"Child pipe not found\");\n-\t\texit(1);\n-\t}\n-\tpipenum = atoi(val);\n-\tsnprintf(buf, sizeof(buf), \"%d\", pipenum);\n-\tif (strcmp(val, buf)) {\n-\t\tpr_perror(\"Unable to parse _LIBCONTAINER_INITPIPE\");\n-\t\texit(1);\n-\t}\n+\t// Retrieve the netlink header\n+\tstruct nlmsghdr nl_msg_hdr;\n+\tint len;\n \n-\tchar nlbuf[NLMSG_HDRLEN];\n-\tstruct nlmsghdr *nh;\n-\tif ((n = read(pipenum, nlbuf, NLMSG_HDRLEN)) != NLMSG_HDRLEN) {\n-\t\tpr_perror(\"Failed to read netlink header, got %d\", n);\n+\tif ((len = read(pipenum, &nl_msg_hdr, NLMSG_HDRLEN)) != NLMSG_HDRLEN) {\n+\t\tpr_perror(\"Failed to read netlink header, got %d instead of %d\",\n+\t\t\t  len, NLMSG_HDRLEN);\n \t\texit(1);\n \t}\n \n-\tnh = (struct nlmsghdr *)nlbuf;\n-\tif (nh->nlmsg_type == NLMSG_ERROR) {\n-\t\tpr_perror(\"Invalid netlink header message\");\n+\tif (nl_msg_hdr.nlmsg_type == NLMSG_ERROR) {\n+\t\tpr_perror(\"failed to read netlink message\");\n \t\texit(1);\n \t}\n-\tif (nh->nlmsg_type != INIT_MSG) {\n-\t\tpr_perror(\"Unexpected netlink message type %d\", nh->nlmsg_type);\n+\tif (nl_msg_hdr.nlmsg_type != INIT_MSG) {\n+\t\tpr_perror(\"unexpected msg type %d\", nl_msg_hdr.nlmsg_type);\n \t\texit(1);\n \t}\n-\t// read the netlink payload\n-\tlen = NLMSG_PAYLOAD(nh, 0);\n-\tchar data[len];\n-\tif ((n = read(pipenum, data, len)) != len) {\n-\t\tpr_perror(\"Failed to read netlink payload, got %d\", n);\n+\t// Retrieve data\n+\tint nl_total_size = NLMSG_PAYLOAD(&nl_msg_hdr, 0);\n+\tchar data[nl_total_size];\n+\n+\tif ((len = read(pipenum, data, nl_total_size)) != nl_total_size) {\n+\t\tpr_perror\n+\t\t    (\"Failed to read netlink payload, got %d instead of %d\",\n+\t\t     len, nl_total_size);\n \t\texit(1);\n \t}\n-\n+\t// Process the passed attributes\n \tint start = 0;\n-\tstruct nlattr *attr;\n-\twhile (start < len) {\n-\t\tint payload_len;\n-\t\tattr = (struct nlattr *)((void *)data + start);\n+\tuint32_t cloneflags = -1;\n+\tuint8_t is_setgroup = 0;\n+\tint consolefd = -1;\n+\tint uidmap_start = -1, uidmap_len = -1;\n+\tint gidmap_start = -1, gidmap_len = -1;\n+\tint payload_len;\n+\tstruct nlattr *nlattr;\n+\n+\twhile (start < nl_total_size) {\n+\t\tnlattr = (struct nlattr *)(data + start);\n \t\tstart += NLA_HDRLEN;\n-\t\tpayload_len = attr->nla_len - NLA_HDRLEN;\n-\t\tswitch (attr->nla_type) {\n-\t\tcase PID_ATTR:\n-\t\t\tpid = (pid_t) readint32(data + start);\n-\t\t\tbreak;\n-\t\tcase CONSOLE_PATH_ATTR:\n-\t\t\tconsolefd = open((char *)data + start, O_RDWR);\n+\t\tpayload_len = nlattr->nla_len - NLA_HDRLEN;\n+\n+\t\tif (nlattr->nla_type == CLONE_FLAGS_ATTR) {\n+\t\t\tcloneflags = readint32(data + start);\n+\t\t} else if (nlattr->nla_type == CONSOLE_PATH_ATTR) {\n+\t\t\t// get the console path before setns because it may change mnt namespace\n+\t\t\tconsolefd = open(data + start, O_RDWR);\n \t\t\tif (consolefd < 0) {\n-\t\t\t\tpr_perror(\"Failed to open console %s\", (char *)data + start);\n+\t\t\t\tpr_perror(\"Failed to open console %s\",\n+\t\t\t\t\t  data + start);\n \t\t\t\texit(1);\n \t\t\t}\n-\t\t\tbreak;\n-\t\t}\n-\t\tstart += NLA_ALIGN(payload_len);\n-\t}\n+\t\t} else if (nlattr->nla_type == NS_PATHS_ATTR) {\n+\t\t\tchar nspaths[payload_len + 1];\n \n-\t// required pid to be passed\n-\tif (pid == 0) {\n-\t\tpr_perror(\"missing pid\");\n-\t\texit(1);\n-\t}\n+\t\t\tstrncpy(nspaths, data + start, payload_len);\n+\t\t\tnspaths[payload_len] = '\\0';\n \n-\t/* Check that the specified process exists */\n-\tsnprintf(buf, PATH_MAX - 1, \"/proc/%d/ns\", pid);\n-\ttfd = open(buf, O_DIRECTORY | O_RDONLY);\n-\tif (tfd == -1) {\n-\t\tpr_perror(\"Failed to open \\\"%s\\\"\", buf);\n-\t\texit(1);\n-\t}\n-\n-\tself_tfd = open(\"/proc/self/ns\", O_DIRECTORY | O_RDONLY);\n-\tif (self_tfd == -1) {\n-\t\tpr_perror(\"Failed to open /proc/self/ns\");\n-\t\texit(1);\n-\t}\n+\t\t\t// if custom namespaces are required, open all descriptors and perform\n+\t\t\t// setns on them\n+\t\t\tint nslen = num_namespaces(nspaths);\n+\t\t\tint fds[nslen];\n+\t\t\tchar *nslist[nslen];\n+\t\t\tint i;\n+\t\t\tchar *ns, *saveptr;\n \n-\tfor (i = 0; i < num; i++) {\n-\t\tstruct stat st;\n-\t\tstruct stat self_st;\n-\t\tint fd;\n+\t\t\tfor (i = 0; i < nslen; i++) {\n+\t\t\t\tchar *str = NULL;\n \n-\t\t/* Symlinks on all namespaces exist for dead processes, but they can't be opened */\n-\t\tif (fstatat(tfd, namespaces[i], &st, 0) == -1) {\n-\t\t\t// Ignore nonexistent namespaces.\n-\t\t\tif (errno == ENOENT)\n-\t\t\t\tcontinue;\n-\t\t}\n-\n-\t\t/* Skip namespaces we're already part of */\n-\t\tif (fstatat(self_tfd, namespaces[i], &self_st, 0) != -1 && st.st_ino == self_st.st_ino) {\n-\t\t\tcontinue;\n-\t\t}\n+\t\t\t\tif (i == 0) {\n+\t\t\t\t\tstr = nspaths;\n+\t\t\t\t}\n+\t\t\t\tns = strtok_r(str, \",\", &saveptr);\n+\t\t\t\tif (ns == NULL) {\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tfds[i] = open(ns, O_RDONLY);\n+\t\t\t\tif (fds[i] == -1) {\n+\t\t\t\t\tpr_perror(\"Failed to open %s\", ns);\n+\t\t\t\t\texit(1);\n+\t\t\t\t}\n+\t\t\t\tnslist[i] = ns;\n+\t\t\t}\n \n-\t\tfd = openat(tfd, namespaces[i], O_RDONLY);\n-\t\tif (fd == -1) {\n-\t\t\tpr_perror(\"Failed to open ns file %s for ns %s\", buf, namespaces[i]);\n-\t\t\texit(1);\n-\t\t}\n-\t\t// Set the namespace.\n-\t\tif (setns(fd, 0) == -1) {\n-\t\t\tpr_perror(\"Failed to setns for %s\", namespaces[i]);\n+\t\t\tfor (i = 0; i < nslen; i++) {\n+\t\t\t\tif (setns(fds[i], 0) != 0) {","path":"libcontainer/nsenter/nsexec.c","position":325,"original_position":325,"commit_id":"b3b5961031b3170c05a1552bd4a6c5ad1556c98b","original_commit_id":"b3b5961031b3170c05a1552bd4a6c5ad1556c98b","user":{"login":"mlaventure","id":16065150,"avatar_url":"https://avatars.githubusercontent.com/u/16065150?v=3","gravatar_id":"","url":"https://api.github.com/users/mlaventure","html_url":"https://github.com/mlaventure","followers_url":"https://api.github.com/users/mlaventure/followers","following_url":"https://api.github.com/users/mlaventure/following{/other_user}","gists_url":"https://api.github.com/users/mlaventure/gists{/gist_id}","starred_url":"https://api.github.com/users/mlaventure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlaventure/subscriptions","organizations_url":"https://api.github.com/users/mlaventure/orgs","repos_url":"https://api.github.com/users/mlaventure/repos","events_url":"https://api.github.com/users/mlaventure/events{/privacy}","received_events_url":"https://api.github.com/users/mlaventure/received_events","type":"User","site_admin":false},"body":"Not sure if it should be libcontainer jobs to check that the provided mapping are correct though","created_at":"2016-01-14T19:59:10Z","updated_at":"2016-01-14T19:59:10Z","html_url":"https://github.com/opencontainers/runc/pull/454#discussion_r49776988","pull_request_url":"https://api.github.com/repos/opencontainers/runc/pulls/454","_links":{"self":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/comments/49776988"},"html":{"href":"https://github.com/opencontainers/runc/pull/454#discussion_r49776988"},"pull_request":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/454"}}},"pull_request":{"url":"https://api.github.com/repos/opencontainers/runc/pulls/454","id":55145608,"html_url":"https://github.com/opencontainers/runc/pull/454","diff_url":"https://github.com/opencontainers/runc/pull/454.diff","patch_url":"https://github.com/opencontainers/runc/pull/454.patch","issue_url":"https://api.github.com/repos/opencontainers/runc/issues/454","number":454,"state":"open","locked":false,"title":"Move setns within nsexec","user":{"login":"mlaventure","id":16065150,"avatar_url":"https://avatars.githubusercontent.com/u/16065150?v=3","gravatar_id":"","url":"https://api.github.com/users/mlaventure","html_url":"https://github.com/mlaventure","followers_url":"https://api.github.com/users/mlaventure/followers","following_url":"https://api.github.com/users/mlaventure/following{/other_user}","gists_url":"https://api.github.com/users/mlaventure/gists{/gist_id}","starred_url":"https://api.github.com/users/mlaventure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlaventure/subscriptions","organizations_url":"https://api.github.com/users/mlaventure/orgs","repos_url":"https://api.github.com/users/mlaventure/repos","events_url":"https://api.github.com/users/mlaventure/events{/privacy}","received_events_url":"https://api.github.com/users/mlaventure/received_events","type":"User","site_admin":false},"body":"This is a rebase of https://github.com/opencontainers/runc/pull/105.\r\n\r\nIt move the `setns` calls within the init C code. This allows for namespaces that only affect future children (e.g. `NEWPID`) to correctly apply to created containers. \r\n","created_at":"2016-01-05T21:30:11Z","updated_at":"2016-01-14T19:59:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e409a58d70ad402102cf1ae156be83892f959a71","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/opencontainers/runc/pulls/454/commits","review_comments_url":"https://api.github.com/repos/opencontainers/runc/pulls/454/comments","review_comment_url":"https://api.github.com/repos/opencontainers/runc/pulls/comments{/number}","comments_url":"https://api.github.com/repos/opencontainers/runc/issues/454/comments","statuses_url":"https://api.github.com/repos/opencontainers/runc/statuses/b3b5961031b3170c05a1552bd4a6c5ad1556c98b","head":{"label":"mlaventure:libcontainer-pidns","ref":"libcontainer-pidns","sha":"b3b5961031b3170c05a1552bd4a6c5ad1556c98b","user":{"login":"mlaventure","id":16065150,"avatar_url":"https://avatars.githubusercontent.com/u/16065150?v=3","gravatar_id":"","url":"https://api.github.com/users/mlaventure","html_url":"https://github.com/mlaventure","followers_url":"https://api.github.com/users/mlaventure/followers","following_url":"https://api.github.com/users/mlaventure/following{/other_user}","gists_url":"https://api.github.com/users/mlaventure/gists{/gist_id}","starred_url":"https://api.github.com/users/mlaventure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlaventure/subscriptions","organizations_url":"https://api.github.com/users/mlaventure/orgs","repos_url":"https://api.github.com/users/mlaventure/repos","events_url":"https://api.github.com/users/mlaventure/events{/privacy}","received_events_url":"https://api.github.com/users/mlaventure/received_events","type":"User","site_admin":false},"repo":{"id":49086627,"name":"runc","full_name":"mlaventure/runc","owner":{"login":"mlaventure","id":16065150,"avatar_url":"https://avatars.githubusercontent.com/u/16065150?v=3","gravatar_id":"","url":"https://api.github.com/users/mlaventure","html_url":"https://github.com/mlaventure","followers_url":"https://api.github.com/users/mlaventure/followers","following_url":"https://api.github.com/users/mlaventure/following{/other_user}","gists_url":"https://api.github.com/users/mlaventure/gists{/gist_id}","starred_url":"https://api.github.com/users/mlaventure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlaventure/subscriptions","organizations_url":"https://api.github.com/users/mlaventure/orgs","repos_url":"https://api.github.com/users/mlaventure/repos","events_url":"https://api.github.com/users/mlaventure/events{/privacy}","received_events_url":"https://api.github.com/users/mlaventure/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mlaventure/runc","description":"runc container cli tools","fork":true,"url":"https://api.github.com/repos/mlaventure/runc","forks_url":"https://api.github.com/repos/mlaventure/runc/forks","keys_url":"https://api.github.com/repos/mlaventure/runc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mlaventure/runc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mlaventure/runc/teams","hooks_url":"https://api.github.com/repos/mlaventure/runc/hooks","issue_events_url":"https://api.github.com/repos/mlaventure/runc/issues/events{/number}","events_url":"https://api.github.com/repos/mlaventure/runc/events","assignees_url":"https://api.github.com/repos/mlaventure/runc/assignees{/user}","branches_url":"https://api.github.com/repos/mlaventure/runc/branches{/branch}","tags_url":"https://api.github.com/repos/mlaventure/runc/tags","blobs_url":"https://api.github.com/repos/mlaventure/runc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mlaventure/runc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mlaventure/runc/git/refs{/sha}","trees_url":"https://api.github.com/repos/mlaventure/runc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mlaventure/runc/statuses/{sha}","languages_url":"https://api.github.com/repos/mlaventure/runc/languages","stargazers_url":"https://api.github.com/repos/mlaventure/runc/stargazers","contributors_url":"https://api.github.com/repos/mlaventure/runc/contributors","subscribers_url":"https://api.github.com/repos/mlaventure/runc/subscribers","subscription_url":"https://api.github.com/repos/mlaventure/runc/subscription","commits_url":"https://api.github.com/repos/mlaventure/runc/commits{/sha}","git_commits_url":"https://api.github.com/repos/mlaventure/runc/git/commits{/sha}","comments_url":"https://api.github.com/repos/mlaventure/runc/comments{/number}","issue_comment_url":"https://api.github.com/repos/mlaventure/runc/issues/comments{/number}","contents_url":"https://api.github.com/repos/mlaventure/runc/contents/{+path}","compare_url":"https://api.github.com/repos/mlaventure/runc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mlaventure/runc/merges","archive_url":"https://api.github.com/repos/mlaventure/runc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mlaventure/runc/downloads","issues_url":"https://api.github.com/repos/mlaventure/runc/issues{/number}","pulls_url":"https://api.github.com/repos/mlaventure/runc/pulls{/number}","milestones_url":"https://api.github.com/repos/mlaventure/runc/milestones{/number}","notifications_url":"https://api.github.com/repos/mlaventure/runc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mlaventure/runc/labels{/name}","releases_url":"https://api.github.com/repos/mlaventure/runc/releases{/id}","created_at":"2016-01-05T19:07:03Z","updated_at":"2016-01-05T19:07:04Z","pushed_at":"2016-01-07T18:13:00Z","git_url":"git://github.com/mlaventure/runc.git","ssh_url":"git@github.com:mlaventure/runc.git","clone_url":"https://github.com/mlaventure/runc.git","svn_url":"https://github.com/mlaventure/runc","homepage":"","size":2294,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"opencontainers:master","ref":"master","sha":"f03b7f83177b9b5876bb5ebf92a9407a7fe02e6d","user":{"login":"opencontainers","id":12563465,"avatar_url":"https://avatars.githubusercontent.com/u/12563465?v=3","gravatar_id":"","url":"https://api.github.com/users/opencontainers","html_url":"https://github.com/opencontainers","followers_url":"https://api.github.com/users/opencontainers/followers","following_url":"https://api.github.com/users/opencontainers/following{/other_user}","gists_url":"https://api.github.com/users/opencontainers/gists{/gist_id}","starred_url":"https://api.github.com/users/opencontainers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencontainers/subscriptions","organizations_url":"https://api.github.com/users/opencontainers/orgs","repos_url":"https://api.github.com/users/opencontainers/repos","events_url":"https://api.github.com/users/opencontainers/events{/privacy}","received_events_url":"https://api.github.com/users/opencontainers/received_events","type":"Organization","site_admin":false},"repo":{"id":36960321,"name":"runc","full_name":"opencontainers/runc","owner":{"login":"opencontainers","id":12563465,"avatar_url":"https://avatars.githubusercontent.com/u/12563465?v=3","gravatar_id":"","url":"https://api.github.com/users/opencontainers","html_url":"https://github.com/opencontainers","followers_url":"https://api.github.com/users/opencontainers/followers","following_url":"https://api.github.com/users/opencontainers/following{/other_user}","gists_url":"https://api.github.com/users/opencontainers/gists{/gist_id}","starred_url":"https://api.github.com/users/opencontainers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/opencontainers/subscriptions","organizations_url":"https://api.github.com/users/opencontainers/orgs","repos_url":"https://api.github.com/users/opencontainers/repos","events_url":"https://api.github.com/users/opencontainers/events{/privacy}","received_events_url":"https://api.github.com/users/opencontainers/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/opencontainers/runc","description":"runc container cli tools","fork":false,"url":"https://api.github.com/repos/opencontainers/runc","forks_url":"https://api.github.com/repos/opencontainers/runc/forks","keys_url":"https://api.github.com/repos/opencontainers/runc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/opencontainers/runc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/opencontainers/runc/teams","hooks_url":"https://api.github.com/repos/opencontainers/runc/hooks","issue_events_url":"https://api.github.com/repos/opencontainers/runc/issues/events{/number}","events_url":"https://api.github.com/repos/opencontainers/runc/events","assignees_url":"https://api.github.com/repos/opencontainers/runc/assignees{/user}","branches_url":"https://api.github.com/repos/opencontainers/runc/branches{/branch}","tags_url":"https://api.github.com/repos/opencontainers/runc/tags","blobs_url":"https://api.github.com/repos/opencontainers/runc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/opencontainers/runc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/opencontainers/runc/git/refs{/sha}","trees_url":"https://api.github.com/repos/opencontainers/runc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/opencontainers/runc/statuses/{sha}","languages_url":"https://api.github.com/repos/opencontainers/runc/languages","stargazers_url":"https://api.github.com/repos/opencontainers/runc/stargazers","contributors_url":"https://api.github.com/repos/opencontainers/runc/contributors","subscribers_url":"https://api.github.com/repos/opencontainers/runc/subscribers","subscription_url":"https://api.github.com/repos/opencontainers/runc/subscription","commits_url":"https://api.github.com/repos/opencontainers/runc/commits{/sha}","git_commits_url":"https://api.github.com/repos/opencontainers/runc/git/commits{/sha}","comments_url":"https://api.github.com/repos/opencontainers/runc/comments{/number}","issue_comment_url":"https://api.github.com/repos/opencontainers/runc/issues/comments{/number}","contents_url":"https://api.github.com/repos/opencontainers/runc/contents/{+path}","compare_url":"https://api.github.com/repos/opencontainers/runc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/opencontainers/runc/merges","archive_url":"https://api.github.com/repos/opencontainers/runc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/opencontainers/runc/downloads","issues_url":"https://api.github.com/repos/opencontainers/runc/issues{/number}","pulls_url":"https://api.github.com/repos/opencontainers/runc/pulls{/number}","milestones_url":"https://api.github.com/repos/opencontainers/runc/milestones{/number}","notifications_url":"https://api.github.com/repos/opencontainers/runc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/opencontainers/runc/labels{/name}","releases_url":"https://api.github.com/repos/opencontainers/runc/releases{/id}","created_at":"2015-06-05T23:30:45Z","updated_at":"2016-01-14T18:27:16Z","pushed_at":"2016-01-14T19:55:06Z","git_url":"git://github.com/opencontainers/runc.git","ssh_url":"git@github.com:opencontainers/runc.git","clone_url":"https://github.com/opencontainers/runc.git","svn_url":"https://github.com/opencontainers/runc","homepage":"","size":3807,"stargazers_count":2415,"watchers_count":2415,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":288,"mirror_url":null,"open_issues_count":78,"forks":288,"open_issues":78,"watchers":2415,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/454"},"html":{"href":"https://github.com/opencontainers/runc/pull/454"},"issue":{"href":"https://api.github.com/repos/opencontainers/runc/issues/454"},"comments":{"href":"https://api.github.com/repos/opencontainers/runc/issues/454/comments"},"review_comments":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/454/comments"},"review_comment":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/opencontainers/runc/pulls/454/commits"},"statuses":{"href":"https://api.github.com/repos/opencontainers/runc/statuses/b3b5961031b3170c05a1552bd4a6c5ad1556c98b"}}}}