{"action":"created","comment":{"url":"https://api.github.com/repos/coreos/rkt/pulls/comments/48030436","id":48030436,"diff_hunk":"@@ -0,0 +1,381 @@\n+// Copyright 2015 The rkt Authors\n+//\n+// Licensed under the Apache License, Version 2.0 (the \"License\");\n+// you may not use this file except in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+//     http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS IS\" BASIS,\n+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+// See the License for the specific language governing permissions and\n+// limitations under the License.\n+\n+package main\n+\n+import (\n+\t\"bufio\"\n+\t\"flag\"\n+\t\"fmt\"\n+\t\"io/ioutil\"\n+\t\"log\"\n+\t\"os\"\n+\t\"path/filepath\"\n+\t\"strings\"\n+\t\"syscall\"\n+\n+\tstage1commontypes \"github.com/coreos/rkt/stage1_common/types\"\n+\n+\t\"github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema\"\n+\t\"github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types\"\n+\n+\t\"github.com/coreos/rkt/common\"\n+\t\"github.com/coreos/rkt/pkg/sys\"\n+)\n+\n+const (\n+\tflavor = \"fly\"\n+)\n+\n+type flyMount struct {\n+\tHostPath         string\n+\tTargetPrefixPath string\n+\tRelTargetPath    string\n+\tFs               string\n+\tFlags            uintptr\n+}\n+\n+type volumeMountTuple struct {\n+\tV types.Volume\n+\tM schema.Mount\n+}\n+\n+var (\n+\tdebug bool\n+\n+\tdiscardNetlist common.NetList\n+\tdiscardBool    bool\n+\tdiscardString  string\n+)\n+\n+func getHostMounts() (map[string]struct{}, error) {\n+\thostMounts := map[string]struct{}{}\n+\n+\tmi, err := os.Open(\"/proc/self/mountinfo\")\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\tdefer mi.Close()\n+\n+\tsc := bufio.NewScanner(mi)\n+\tfor sc.Scan() {\n+\t\tvar (\n+\t\t\tdiscard    string\n+\t\t\tmountPoint string\n+\t\t)\n+\n+\t\t_, err := fmt.Sscanf(sc.Text(),\n+\t\t\t\"%s %s %s %s %s\",\n+\t\t\t&discard, &discard, &discard, &discard, &mountPoint,\n+\t\t)\n+\t\tif err != nil {\n+\t\t\treturn nil, err\n+\t\t}\n+\n+\t\thostMounts[mountPoint] = struct{}{}\n+\t}\n+\tif sc.Err() != nil {\n+\t\treturn nil, fmt.Errorf(\"problem parsing mountinfo: %v\", sc.Err())\n+\t}\n+\treturn hostMounts, nil\n+}\n+\n+func init() {\n+\tflag.BoolVar(&debug, \"debug\", false, \"Run in debug mode\")\n+\n+\t// The following flags need to be supported by stage1 according to\n+\t// https://github.com/coreos/rkt/blob/master/Documentation/devel/stage1-implementors-guide.md\n+\t// TODO: either implement functionality or give not implemented warnings\n+\tflag.Var(&discardNetlist, \"net\", \"Setup networking\")\n+\tflag.BoolVar(&discardBool, \"interactive\", true, \"The pod is interactive\")\n+\tflag.StringVar(&discardString, \"mds-token\", \"\", \"MDS auth token\")\n+\tflag.StringVar(&discardString, \"local-config\", common.DefaultLocalConfigDir, \"Local config path\")\n+}\n+\n+func lookupPath(bin string, paths string) (string, error) {\n+\tpathsArr := filepath.SplitList(paths)\n+\tfor _, path := range pathsArr {\n+\t\tbinPath := filepath.Join(path, bin)\n+\t\tbinAbsPath, err := filepath.Abs(binPath)\n+\t\tif err != nil {\n+\t\t\treturn \"\", fmt.Errorf(\"unable to find absolute path for %s\", binPath)\n+\t\t}\n+\t\td, err := os.Stat(binAbsPath)\n+\t\tif err != nil {\n+\t\t\tcontinue\n+\t\t}\n+\t\t// Check the executable bit, inspired by os.exec.LookPath()\n+\t\tif m := d.Mode(); !m.IsDir() && m&0111 != 0 {\n+\t\t\treturn binAbsPath, nil\n+\t\t}\n+\t}\n+\treturn \"\", fmt.Errorf(\"unable to find %q in %q\", bin, paths)\n+}\n+\n+func withClearedCloExec(lfd int, f func() error) error {\n+\terr := sys.CloseOnExec(lfd, false)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tdefer sys.CloseOnExec(lfd, true)\n+\n+\treturn f()\n+}\n+\n+func writePpid(pid int) error {\n+\t// write ppid file as specified in\n+\t// Documentation/devel/stage1-implementors-guide.md\n+\tout, err := os.Getwd()\n+\tif err != nil {\n+\t\treturn fmt.Errorf(\"Cannot get current working directory: %v\\n\", err)\n+\t}\n+\t// we are the parent of the process that is PID 1 in the container so we write our PID to \"ppid\"\n+\terr = ioutil.WriteFile(filepath.Join(out, \"ppid\"),\n+\t\t[]byte(fmt.Sprintf(\"%d\\n\", pid)), 0644)\n+\tif err != nil {\n+\t\treturn fmt.Errorf(\"Cannot write ppid file: %v\\n\", err)\n+\t}\n+\treturn nil\n+}\n+\n+func evaluateMounts(rfs string, app string, p *stage1commontypes.Pod) ([]flyMount, error) {\n+\timApp := p.Images[app].App\n+\tnamedVolumeMounts := map[types.ACName]volumeMountTuple{}\n+\n+\tfor _, m := range p.Manifest.Apps[0].Mounts {\n+\t\t_, exists := namedVolumeMounts[m.Volume]\n+\t\tif exists {\n+\t\t\tlog.Fatalf(\"fly: duplicated mount given: %q\", m.Volume)\n+\t\t}\n+\t\tnamedVolumeMounts[m.Volume] = volumeMountTuple{M: m}\n+\t\tlog.Printf(\"Adding %+v\", namedVolumeMounts[m.Volume])\n+\t}\n+\n+\t// Merge command-line Mounts with ImageManifest's MountPoints\n+\tfor _, mp := range imApp.MountPoints {\n+\t\ttuple, exists := namedVolumeMounts[mp.Name]\n+\t\tswitch {\n+\t\tcase exists && tuple.M.Path != mp.Path:\n+\t\t\treturn nil, fmt.Errorf(\"fly: conflicting path information from mount and mountpoint %q\", mp.Name)\n+\t\tcase !exists:\n+\t\t\tnamedVolumeMounts[mp.Name] = volumeMountTuple{M: schema.Mount{Volume: mp.Name, Path: mp.Path}}\n+\t\t\tlog.Printf(\"Adding %+v\", namedVolumeMounts[mp.Name])\n+\t\t}\n+\t}\n+\n+\t// Insert the command-line Volumes\n+\tfor _, v := range p.Manifest.Volumes {\n+\t\t// Check if we have a mount for this volume\n+\t\ttuple, exists := namedVolumeMounts[v.Name]\n+\t\tif !exists {\n+\t\t\treturn nil, fmt.Errorf(\"fly: missing mount for volume %q\", v.Name)\n+\t\t} else if tuple.M.Volume != v.Name {\n+\t\t\t// assertion regarding the implementation, should never happen\n+\t\t\treturn nil, fmt.Errorf(\"fly: mismatched volume:mount pair: %q != %q\", v.Name, tuple.M.Volume)\n+\t\t}\n+\t\tnamedVolumeMounts[v.Name] = volumeMountTuple{V: v, M: tuple.M}\n+\t\tlog.Printf(\"Adding %+v\", namedVolumeMounts[v.Name])\n+\t}\n+\n+\t// Merge command-line Volumes with ImageManifest's MountPoints\n+\tfor _, mp := range imApp.MountPoints {\n+\t\t// Check if we have a volume for this mountpoint\n+\t\ttuple, exists := namedVolumeMounts[mp.Name]\n+\t\tif !exists || tuple.V.Name == \"\" {\n+\t\t\tlog.Fatalf(\"fly: missing volume for mountpoint %q\", mp.Name)\n+\t\t}\n+\n+\t\t// If empty, fill in ReadOnly bit\n+\t\tif tuple.V.ReadOnly == nil {\n+\t\t\tv := tuple.V\n+\t\t\tv.ReadOnly = &mp.ReadOnly\n+\t\t\tnamedVolumeMounts[mp.Name] = volumeMountTuple{M: tuple.M, V: v}\n+\t\t\tlog.Printf(\"Adding %+v\", namedVolumeMounts[mp.Name])\n+\t\t}\n+\t}\n+\n+\t// Gather host mounts which we make MS_SHARED if passed as a volume source\n+\thostMounts, err := getHostMounts()\n+\tif err != nil {\n+\t\tlog.Fatalf(\"fly: error gathering host mounts\")\n+\t}\n+\n+\targFlyMounts := []flyMount{}\n+\tvar flags uintptr = syscall.MS_BIND // TODO: allow optional | syscall.MS_REC\n+\tfor _, tuple := range namedVolumeMounts {\n+\t\tif _, isHostMount := hostMounts[tuple.V.Source]; isHostMount {\n+\t\t\t// Mark the host mount as SHARED so the container's changes to the mount are propagated to the host\n+\t\t\targFlyMounts = append(argFlyMounts,\n+\t\t\t\tflyMount{\"\", \"\", tuple.V.Source, \"none\", syscall.MS_REC | syscall.MS_SHARED},\n+\t\t\t)\n+\t\t}\n+\t\targFlyMounts = append(argFlyMounts,\n+\t\t\tflyMount{tuple.V.Source, rfs, tuple.M.Path, \"none\", flags},\n+\t\t)\n+\n+\t\tif tuple.V.ReadOnly != nil && *tuple.V.ReadOnly {\n+\t\t\targFlyMounts = append(argFlyMounts,\n+\t\t\t\tflyMount{\"\", rfs, tuple.M.Path, \"none\", flags | syscall.MS_REMOUNT | syscall.MS_RDONLY},\n+\t\t\t)\n+\t\t}\n+\t}\n+\treturn argFlyMounts, nil\n+}\n+\n+func stage1() int {\n+\tuuid, err := types.NewUUID(flag.Arg(0))\n+\tif err != nil {\n+\t\tfmt.Fprintln(os.Stderr, \"UUID is missing or malformed\")\n+\t\treturn 1\n+\t}\n+\n+\troot := \".\"\n+\tp, err := stage1commontypes.LoadPod(root, uuid)\n+\tif err != nil {\n+\t\tfmt.Fprintf(os.Stderr, \"Failed to load pod: %v\\n\", err)\n+\t\treturn 1\n+\t}\n+\n+\tif len(p.Manifest.Apps) != 1 {\n+\t\tlog.Fatalf(\"Flavor %q only supports 1 application per Pod for now.\", flavor)\n+\t}\n+\n+\t// TODO: insert environment from manifest\n+\tenv := []string{\"PATH=/bin:/sbin:/usr/bin:/usr/local/bin\"}\n+\targs := p.Manifest.Apps[0].App.Exec\n+\trfs := filepath.Join(common.AppPath(p.Root, p.Manifest.Apps[0].Name), \"rootfs\")\n+\n+\t// set close-on-exec flag on RKT_LOCK_FD so it gets correctly closed when invoking\n+\t// network plugins\n+\tlfd, err := common.GetRktLockFD()\n+\tif err != nil {\n+\t\tfmt.Fprintf(os.Stderr, \"Failed to get rkt lock fd: %v\\n\", err)\n+\t\treturn 1\n+\t}\n+\n+\tif err := sys.CloseOnExec(lfd, true); err != nil {\n+\t\tfmt.Fprintf(os.Stderr, \"Failed to set FD_CLOEXEC on rkt lock: %v\\n\", err)\n+\t\treturn 1\n+\t}\n+\n+\targFlyMounts, err := evaluateMounts(rfs, string(p.Manifest.Apps[0].Name), p)\n+\tif err != nil {\n+\t\tlog.Fatalf(\"Error evaluating mounts: %v\", err)\n+\t}\n+\n+\teffectiveMounts := append(\n+\t\t[]flyMount{\n+\t\t\t{\"\", \"\", \"/dev\", \"none\", syscall.MS_REC | syscall.MS_SHARED},\n+\t\t\t{\"/dev\", rfs, \"/dev\", \"none\", syscall.MS_BIND | syscall.MS_REC},","path":"stage1_fly/run/main.go","position":280,"original_position":280,"commit_id":"871986bbcff7e92dbd200b5c9d937e01736ba812","original_commit_id":"3fb3fa23120bdd194adf4ea12bff8d679cd854ae","user":{"login":"steveeJ","id":1181362,"avatar_url":"https://avatars.githubusercontent.com/u/1181362?v=3","gravatar_id":"","url":"https://api.github.com/users/steveeJ","html_url":"https://github.com/steveeJ","followers_url":"https://api.github.com/users/steveeJ/followers","following_url":"https://api.github.com/users/steveeJ/following{/other_user}","gists_url":"https://api.github.com/users/steveeJ/gists{/gist_id}","starred_url":"https://api.github.com/users/steveeJ/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveeJ/subscriptions","organizations_url":"https://api.github.com/users/steveeJ/orgs","repos_url":"https://api.github.com/users/steveeJ/repos","events_url":"https://api.github.com/users/steveeJ/events{/privacy}","received_events_url":"https://api.github.com/users/steveeJ/received_events","type":"User","site_admin":false},"body":"I thought of applications that might alter `/dev` by instrumenting the device-mapper. I thought it is useful for people who need it, and might not bother others since they must be aware of the risks of fly anyway. I don't insist on this though, and I can see the risky side too. If you insist on making it a slave I will.","created_at":"2015-12-18T14:41:50Z","updated_at":"2015-12-18T14:41:50Z","html_url":"https://github.com/coreos/rkt/pull/1833#discussion_r48030436","pull_request_url":"https://api.github.com/repos/coreos/rkt/pulls/1833","_links":{"self":{"href":"https://api.github.com/repos/coreos/rkt/pulls/comments/48030436"},"html":{"href":"https://github.com/coreos/rkt/pull/1833#discussion_r48030436"},"pull_request":{"href":"https://api.github.com/repos/coreos/rkt/pulls/1833"}}},"pull_request":{"url":"https://api.github.com/repos/coreos/rkt/pulls/1833","id":52611721,"html_url":"https://github.com/coreos/rkt/pull/1833","diff_url":"https://github.com/coreos/rkt/pull/1833.diff","patch_url":"https://github.com/coreos/rkt/pull/1833.patch","issue_url":"https://api.github.com/repos/coreos/rkt/issues/1833","number":1833,"state":"open","locked":false,"title":"initial implementation of rkt fly as stage1","user":{"login":"steveeJ","id":1181362,"avatar_url":"https://avatars.githubusercontent.com/u/1181362?v=3","gravatar_id":"","url":"https://api.github.com/users/steveeJ","html_url":"https://github.com/steveeJ","followers_url":"https://api.github.com/users/steveeJ/followers","following_url":"https://api.github.com/users/steveeJ/following{/other_user}","gists_url":"https://api.github.com/users/steveeJ/gists{/gist_id}","starred_url":"https://api.github.com/users/steveeJ/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveeJ/subscriptions","organizations_url":"https://api.github.com/users/steveeJ/orgs","repos_url":"https://api.github.com/users/steveeJ/repos","events_url":"https://api.github.com/users/steveeJ/events{/privacy}","received_events_url":"https://api.github.com/users/steveeJ/received_events","type":"User","site_admin":false},"body":"Alternative proposal for #1825\r\n\r\n- [ ] refactor package names\r\n- [ ] add CHANGELOG entry\r\n- [ ] add documentation","created_at":"2015-12-03T23:58:19Z","updated_at":"2015-12-18T14:41:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6e799f4274b68d2cf188542d7f397135427492c2","assignee":null,"milestone":{"url":"https://api.github.com/repos/coreos/rkt/milestones/25","html_url":"https://github.com/coreos/rkt/milestones/v0.14.0","labels_url":"https://api.github.com/repos/coreos/rkt/milestones/25/labels","id":1408793,"number":25,"title":"v0.14.0","description":"","creator":{"login":"alban","id":27575,"avatar_url":"https://avatars.githubusercontent.com/u/27575?v=3","gravatar_id":"","url":"https://api.github.com/users/alban","html_url":"https://github.com/alban","followers_url":"https://api.github.com/users/alban/followers","following_url":"https://api.github.com/users/alban/following{/other_user}","gists_url":"https://api.github.com/users/alban/gists{/gist_id}","starred_url":"https://api.github.com/users/alban/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alban/subscriptions","organizations_url":"https://api.github.com/users/alban/orgs","repos_url":"https://api.github.com/users/alban/repos","events_url":"https://api.github.com/users/alban/events{/privacy}","received_events_url":"https://api.github.com/users/alban/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":41,"state":"open","created_at":"2015-11-12T16:51:31Z","updated_at":"2015-12-18T14:33:05Z","due_on":"2015-12-16T23:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/coreos/rkt/pulls/1833/commits","review_comments_url":"https://api.github.com/repos/coreos/rkt/pulls/1833/comments","review_comment_url":"https://api.github.com/repos/coreos/rkt/pulls/comments{/number}","comments_url":"https://api.github.com/repos/coreos/rkt/issues/1833/comments","statuses_url":"https://api.github.com/repos/coreos/rkt/statuses/871986bbcff7e92dbd200b5c9d937e01736ba812","head":{"label":"steveeJ:flystage1","ref":"flystage1","sha":"871986bbcff7e92dbd200b5c9d937e01736ba812","user":{"login":"steveeJ","id":1181362,"avatar_url":"https://avatars.githubusercontent.com/u/1181362?v=3","gravatar_id":"","url":"https://api.github.com/users/steveeJ","html_url":"https://github.com/steveeJ","followers_url":"https://api.github.com/users/steveeJ/followers","following_url":"https://api.github.com/users/steveeJ/following{/other_user}","gists_url":"https://api.github.com/users/steveeJ/gists{/gist_id}","starred_url":"https://api.github.com/users/steveeJ/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveeJ/subscriptions","organizations_url":"https://api.github.com/users/steveeJ/orgs","repos_url":"https://api.github.com/users/steveeJ/repos","events_url":"https://api.github.com/users/steveeJ/events{/privacy}","received_events_url":"https://api.github.com/users/steveeJ/received_events","type":"User","site_admin":false},"repo":{"id":34967118,"name":"rkt","full_name":"steveeJ/rkt","owner":{"login":"steveeJ","id":1181362,"avatar_url":"https://avatars.githubusercontent.com/u/1181362?v=3","gravatar_id":"","url":"https://api.github.com/users/steveeJ","html_url":"https://github.com/steveeJ","followers_url":"https://api.github.com/users/steveeJ/followers","following_url":"https://api.github.com/users/steveeJ/following{/other_user}","gists_url":"https://api.github.com/users/steveeJ/gists{/gist_id}","starred_url":"https://api.github.com/users/steveeJ/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveeJ/subscriptions","organizations_url":"https://api.github.com/users/steveeJ/orgs","repos_url":"https://api.github.com/users/steveeJ/repos","events_url":"https://api.github.com/users/steveeJ/events{/privacy}","received_events_url":"https://api.github.com/users/steveeJ/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/steveeJ/rkt","description":"rkt is an App Container runtime for Linux","fork":true,"url":"https://api.github.com/repos/steveeJ/rkt","forks_url":"https://api.github.com/repos/steveeJ/rkt/forks","keys_url":"https://api.github.com/repos/steveeJ/rkt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/steveeJ/rkt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/steveeJ/rkt/teams","hooks_url":"https://api.github.com/repos/steveeJ/rkt/hooks","issue_events_url":"https://api.github.com/repos/steveeJ/rkt/issues/events{/number}","events_url":"https://api.github.com/repos/steveeJ/rkt/events","assignees_url":"https://api.github.com/repos/steveeJ/rkt/assignees{/user}","branches_url":"https://api.github.com/repos/steveeJ/rkt/branches{/branch}","tags_url":"https://api.github.com/repos/steveeJ/rkt/tags","blobs_url":"https://api.github.com/repos/steveeJ/rkt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/steveeJ/rkt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/steveeJ/rkt/git/refs{/sha}","trees_url":"https://api.github.com/repos/steveeJ/rkt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/steveeJ/rkt/statuses/{sha}","languages_url":"https://api.github.com/repos/steveeJ/rkt/languages","stargazers_url":"https://api.github.com/repos/steveeJ/rkt/stargazers","contributors_url":"https://api.github.com/repos/steveeJ/rkt/contributors","subscribers_url":"https://api.github.com/repos/steveeJ/rkt/subscribers","subscription_url":"https://api.github.com/repos/steveeJ/rkt/subscription","commits_url":"https://api.github.com/repos/steveeJ/rkt/commits{/sha}","git_commits_url":"https://api.github.com/repos/steveeJ/rkt/git/commits{/sha}","comments_url":"https://api.github.com/repos/steveeJ/rkt/comments{/number}","issue_comment_url":"https://api.github.com/repos/steveeJ/rkt/issues/comments{/number}","contents_url":"https://api.github.com/repos/steveeJ/rkt/contents/{+path}","compare_url":"https://api.github.com/repos/steveeJ/rkt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/steveeJ/rkt/merges","archive_url":"https://api.github.com/repos/steveeJ/rkt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/steveeJ/rkt/downloads","issues_url":"https://api.github.com/repos/steveeJ/rkt/issues{/number}","pulls_url":"https://api.github.com/repos/steveeJ/rkt/pulls{/number}","milestones_url":"https://api.github.com/repos/steveeJ/rkt/milestones{/number}","notifications_url":"https://api.github.com/repos/steveeJ/rkt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/steveeJ/rkt/labels{/name}","releases_url":"https://api.github.com/repos/steveeJ/rkt/releases{/id}","created_at":"2015-05-02T23:42:32Z","updated_at":"2015-05-02T23:42:50Z","pushed_at":"2015-12-18T12:07:10Z","git_url":"git://github.com/steveeJ/rkt.git","ssh_url":"git@github.com:steveeJ/rkt.git","clone_url":"https://github.com/steveeJ/rkt.git","svn_url":"https://github.com/steveeJ/rkt","homepage":"","size":17931,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"coreos:master","ref":"master","sha":"faee138c9a397c975311692903a6eb168e2178ea","user":{"login":"coreos","id":3730757,"avatar_url":"https://avatars.githubusercontent.com/u/3730757?v=3","gravatar_id":"","url":"https://api.github.com/users/coreos","html_url":"https://github.com/coreos","followers_url":"https://api.github.com/users/coreos/followers","following_url":"https://api.github.com/users/coreos/following{/other_user}","gists_url":"https://api.github.com/users/coreos/gists{/gist_id}","starred_url":"https://api.github.com/users/coreos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coreos/subscriptions","organizations_url":"https://api.github.com/users/coreos/orgs","repos_url":"https://api.github.com/users/coreos/repos","events_url":"https://api.github.com/users/coreos/events{/privacy}","received_events_url":"https://api.github.com/users/coreos/received_events","type":"Organization","site_admin":false},"repo":{"id":26509369,"name":"rkt","full_name":"coreos/rkt","owner":{"login":"coreos","id":3730757,"avatar_url":"https://avatars.githubusercontent.com/u/3730757?v=3","gravatar_id":"","url":"https://api.github.com/users/coreos","html_url":"https://github.com/coreos","followers_url":"https://api.github.com/users/coreos/followers","following_url":"https://api.github.com/users/coreos/following{/other_user}","gists_url":"https://api.github.com/users/coreos/gists{/gist_id}","starred_url":"https://api.github.com/users/coreos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coreos/subscriptions","organizations_url":"https://api.github.com/users/coreos/orgs","repos_url":"https://api.github.com/users/coreos/repos","events_url":"https://api.github.com/users/coreos/events{/privacy}","received_events_url":"https://api.github.com/users/coreos/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/coreos/rkt","description":"rkt is an App Container runtime for Linux","fork":false,"url":"https://api.github.com/repos/coreos/rkt","forks_url":"https://api.github.com/repos/coreos/rkt/forks","keys_url":"https://api.github.com/repos/coreos/rkt/keys{/key_id}","collaborators_url":"https://api.github.com/repos/coreos/rkt/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/coreos/rkt/teams","hooks_url":"https://api.github.com/repos/coreos/rkt/hooks","issue_events_url":"https://api.github.com/repos/coreos/rkt/issues/events{/number}","events_url":"https://api.github.com/repos/coreos/rkt/events","assignees_url":"https://api.github.com/repos/coreos/rkt/assignees{/user}","branches_url":"https://api.github.com/repos/coreos/rkt/branches{/branch}","tags_url":"https://api.github.com/repos/coreos/rkt/tags","blobs_url":"https://api.github.com/repos/coreos/rkt/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/coreos/rkt/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/coreos/rkt/git/refs{/sha}","trees_url":"https://api.github.com/repos/coreos/rkt/git/trees{/sha}","statuses_url":"https://api.github.com/repos/coreos/rkt/statuses/{sha}","languages_url":"https://api.github.com/repos/coreos/rkt/languages","stargazers_url":"https://api.github.com/repos/coreos/rkt/stargazers","contributors_url":"https://api.github.com/repos/coreos/rkt/contributors","subscribers_url":"https://api.github.com/repos/coreos/rkt/subscribers","subscription_url":"https://api.github.com/repos/coreos/rkt/subscription","commits_url":"https://api.github.com/repos/coreos/rkt/commits{/sha}","git_commits_url":"https://api.github.com/repos/coreos/rkt/git/commits{/sha}","comments_url":"https://api.github.com/repos/coreos/rkt/comments{/number}","issue_comment_url":"https://api.github.com/repos/coreos/rkt/issues/comments{/number}","contents_url":"https://api.github.com/repos/coreos/rkt/contents/{+path}","compare_url":"https://api.github.com/repos/coreos/rkt/compare/{base}...{head}","merges_url":"https://api.github.com/repos/coreos/rkt/merges","archive_url":"https://api.github.com/repos/coreos/rkt/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/coreos/rkt/downloads","issues_url":"https://api.github.com/repos/coreos/rkt/issues{/number}","pulls_url":"https://api.github.com/repos/coreos/rkt/pulls{/number}","milestones_url":"https://api.github.com/repos/coreos/rkt/milestones{/number}","notifications_url":"https://api.github.com/repos/coreos/rkt/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/coreos/rkt/labels{/name}","releases_url":"https://api.github.com/repos/coreos/rkt/releases{/id}","created_at":"2014-11-11T23:13:18Z","updated_at":"2015-12-18T06:27:24Z","pushed_at":"2015-12-18T12:07:10Z","git_url":"git://github.com/coreos/rkt.git","ssh_url":"git@github.com:coreos/rkt.git","clone_url":"https://github.com/coreos/rkt.git","svn_url":"https://github.com/coreos/rkt","homepage":"","size":21607,"stargazers_count":4939,"watchers_count":4939,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":420,"mirror_url":null,"open_issues_count":204,"forks":420,"open_issues":204,"watchers":4939,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/coreos/rkt/pulls/1833"},"html":{"href":"https://github.com/coreos/rkt/pull/1833"},"issue":{"href":"https://api.github.com/repos/coreos/rkt/issues/1833"},"comments":{"href":"https://api.github.com/repos/coreos/rkt/issues/1833/comments"},"review_comments":{"href":"https://api.github.com/repos/coreos/rkt/pulls/1833/comments"},"review_comment":{"href":"https://api.github.com/repos/coreos/rkt/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/coreos/rkt/pulls/1833/commits"},"statuses":{"href":"https://api.github.com/repos/coreos/rkt/statuses/871986bbcff7e92dbd200b5c9d937e01736ba812"}}}}