{"action":"created","comment":{"url":"https://api.github.com/repos/mrunalp/ocitools/pulls/comments/45827778","id":45827778,"diff_hunk":"@@ -0,0 +1,372 @@\n+package main\n+\n+import (\n+\t\"encoding/json\"\n+\t\"os\"\n+\t\"path\"\n+\t\"regexp\"\n+\n+\t\"github.com/Sirupsen/logrus\"\n+\t\"github.com/codegangsta/cli\"\n+\t\"github.com/opencontainers/specs\"\n+)\n+\n+var bundleValidateFlags = []cli.Flag{\n+\tcli.StringFlag{Name: \"path\", Usage: \"path to the bundle (could either be a directory or an archived file)\"},\n+}\n+\n+var bundleValidateCommand = cli.Command{\n+\tName:  \"bundleValidate\",\n+\tUsage: \"bundleValidate a OCI spec file\",\n+\tFlags: bundleValidateFlags,\n+\tAction: func(context *cli.Context) {\n+\t\tinputPath := context.String(\"path\")\n+\t\tif inputPath == \"\" {\n+\t\t\tlogrus.Fatalf(\"Bundle path shouldn't be empty\")\n+\t\t}\n+\n+\t\tif fi, err := os.Stat(inputPath); err != nil {\n+\t\t\tlogrus.Fatal(err)\n+\t\t} else if !fi.IsDir() {\n+\t\t\tlogrus.Fatalf(\"The archival format is not defined in OCI yet.\")\n+\t\t}\n+\n+\t\tsf, err := os.Open(path.Join(inputPath, \"config.json\"))\n+\t\tif err != nil {\n+\t\t\tlogrus.Fatal(err)\n+\t\t}\n+\n+\t\tdefer sf.Close()\n+\n+\t\t//TODO: Using protobuf to decode spec, so the 'required' config will be checked automaticly\n+\t\tvar spec specs.LinuxSpec\n+\t\tif err = json.NewDecoder(sf).Decode(&spec); err != nil {\n+\t\t\tlogrus.Fatal(err)\n+\t\t} else {\n+\t\t\tif spec.Platform.OS != \"linux\" {\n+\t\t\t\tlogrus.Fatalf(\"The operation system '%s' of the bundle is not support yet.\", spec.Platform.OS)\n+\t\t\t}\n+\t\t}\n+\n+\t\t//TODO: Using protobuf to decode spec, so the 'required' config will be checked automaticly\n+\t\trf, err := os.Open(path.Join(inputPath, \"runtime.json\"))\n+\t\tif err != nil {\n+\t\t\tlogrus.Fatal(err)\n+\t\t}\n+\t\tdefer rf.Close()\n+\n+\t\tvar runtime specs.LinuxRuntimeSpec\n+\t\tif err = json.NewDecoder(rf).Decode(&runtime); err != nil {\n+\t\t\tlogrus.Fatal(err)\n+\t\t}\n+\n+\t\tbundleValidate(spec, runtime, path.Join(inputPath, \"rootfs\"))\n+\t\tlogrus.Infof(\"Bundle test succeeded.\")\n+\t},\n+}\n+\n+func bundleValidate(spec specs.LinuxSpec, runtime specs.LinuxRuntimeSpec, rootfs string) {\n+\tCheckSemVer(spec.Version)\n+\tCheckMountPoints(spec.Mounts, runtime.Mounts, rootfs)\n+\tCheckLinuxSpec(spec, runtime)\n+\tCheckLinuxRuntime(runtime.Linux, rootfs)\n+}\n+\n+func CheckSemVer(version string) {\n+\tre, _ := regexp.Compile(\"^(\\\\d+)?\\\\.(\\\\d+)?\\\\.(\\\\d+)?$\")\n+\tif ok := re.Match([]byte(version)); !ok {\n+\t\tlogrus.Fatalf(\"%s is not a valid version format, please read 'SemVer v2.0.0'\", version)\n+\t}\n+}\n+\n+func CheckMountPoints(mps []specs.MountPoint, rmps map[string]specs.Mount, rootfs string) {\n+\tfor index := 0; index < len(mps); index++ {\n+\t\tmountPath := path.Join(rootfs, mps[index].Path)\n+\t\tif fi, err := os.Stat(mountPath); err != nil {\n+\t\t\tlogrus.Fatal(err)\n+\t\t} else if !fi.IsDir() {\n+\t\t\tlogrus.Fatalf(\"The mountPoint %s is not a valid directory\", mountPath)\n+\t\t}\n+\n+\t\tif _, ok := rmps[mps[index].Name]; !ok {\n+\t\t\tlogrus.Fatalf(\"%s in config/mount does not exist in runtime/mount\", mps[index].Name)\n+\t\t}\n+\t}\n+}\n+\n+//Linux only\n+func CheckLinuxSpec(spec specs.LinuxSpec, runtime specs.LinuxRuntimeSpec) {\n+\tpaths := requiredPaths()\n+\tfor pIndex := 0; pIndex < len(paths); pIndex++ {\n+\t\tfound := false\n+\t\tfor mIndex := 0; mIndex < len(spec.Spec.Mounts); mIndex++ {\n+\t\t\tmp := spec.Spec.Mounts[mIndex]\n+\t\t\tif paths[pIndex] == mp.Path {\n+\t\t\t\tfound = true\n+\t\t\t\tbreak\n+\t\t\t}\n+\t\t}\n+\t\tif !found {\n+\t\t\tlogrus.Fatalf(\"The mount %s is missing.\", paths[pIndex])\n+\t\t}\n+\t}\n+\n+\tfor index := 0; index < len(spec.Linux.Capabilities); index++ {\n+\t\tcapability := spec.Linux.Capabilities[index]\n+\t\tif !capValid(capability) {\n+\t\t\tlogrus.Fatalf(\"%s is not valid, please see `man capabilities`\", spec.Linux.Capabilities[index])","path":"bundle.go","position":117,"original_position":117,"commit_id":"03949f93e22e7eeb6d81814e9fe5e68f9c35e210","original_commit_id":"03949f93e22e7eeb6d81814e9fe5e68f9c35e210","user":{"login":"mrunalp","id":53798,"avatar_url":"https://avatars.githubusercontent.com/u/53798?v=3","gravatar_id":"","url":"https://api.github.com/users/mrunalp","html_url":"https://github.com/mrunalp","followers_url":"https://api.github.com/users/mrunalp/followers","following_url":"https://api.github.com/users/mrunalp/following{/other_user}","gists_url":"https://api.github.com/users/mrunalp/gists{/gist_id}","starred_url":"https://api.github.com/users/mrunalp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrunalp/subscriptions","organizations_url":"https://api.github.com/users/mrunalp/orgs","repos_url":"https://api.github.com/users/mrunalp/repos","events_url":"https://api.github.com/users/mrunalp/events{/privacy}","received_events_url":"https://api.github.com/users/mrunalp/received_events","type":"User","site_admin":false},"body":"man capabilities(7)","created_at":"2015-11-25T04:06:42Z","updated_at":"2015-11-25T04:06:42Z","html_url":"https://github.com/mrunalp/ocitools/pull/10#discussion_r45827778","pull_request_url":"https://api.github.com/repos/mrunalp/ocitools/pulls/10","_links":{"self":{"href":"https://api.github.com/repos/mrunalp/ocitools/pulls/comments/45827778"},"html":{"href":"https://github.com/mrunalp/ocitools/pull/10#discussion_r45827778"},"pull_request":{"href":"https://api.github.com/repos/mrunalp/ocitools/pulls/10"}}},"pull_request":{"url":"https://api.github.com/repos/mrunalp/ocitools/pulls/10","id":51625946,"html_url":"https://github.com/mrunalp/ocitools/pull/10","diff_url":"https://github.com/mrunalp/ocitools/pull/10.diff","patch_url":"https://github.com/mrunalp/ocitools/pull/10.patch","issue_url":"https://api.github.com/repos/mrunalp/ocitools/issues/10","number":10,"state":"open","locked":false,"title":"add bundle.go to verify a bundle","user":{"login":"liangchenye","id":13341875,"avatar_url":"https://avatars.githubusercontent.com/u/13341875?v=3","gravatar_id":"","url":"https://api.github.com/users/liangchenye","html_url":"https://github.com/liangchenye","followers_url":"https://api.github.com/users/liangchenye/followers","following_url":"https://api.github.com/users/liangchenye/following{/other_user}","gists_url":"https://api.github.com/users/liangchenye/gists{/gist_id}","starred_url":"https://api.github.com/users/liangchenye/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liangchenye/subscriptions","organizations_url":"https://api.github.com/users/liangchenye/orgs","repos_url":"https://api.github.com/users/liangchenye/repos","events_url":"https://api.github.com/users/liangchenye/events{/privacy}","received_events_url":"https://api.github.com/users/liangchenye/received_events","type":"User","site_admin":false},"body":"Signed-off-by: liangchenye <liangchenye@huawei.com>","created_at":"2015-11-24T07:38:10Z","updated_at":"2015-11-25T04:06:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9cf5c7a56d9f92d430e56acd29fba5def5ea2ced","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mrunalp/ocitools/pulls/10/commits","review_comments_url":"https://api.github.com/repos/mrunalp/ocitools/pulls/10/comments","review_comment_url":"https://api.github.com/repos/mrunalp/ocitools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mrunalp/ocitools/issues/10/comments","statuses_url":"https://api.github.com/repos/mrunalp/ocitools/statuses/03949f93e22e7eeb6d81814e9fe5e68f9c35e210","head":{"label":"liangchenye:bundlevalidate","ref":"bundlevalidate","sha":"03949f93e22e7eeb6d81814e9fe5e68f9c35e210","user":{"login":"liangchenye","id":13341875,"avatar_url":"https://avatars.githubusercontent.com/u/13341875?v=3","gravatar_id":"","url":"https://api.github.com/users/liangchenye","html_url":"https://github.com/liangchenye","followers_url":"https://api.github.com/users/liangchenye/followers","following_url":"https://api.github.com/users/liangchenye/following{/other_user}","gists_url":"https://api.github.com/users/liangchenye/gists{/gist_id}","starred_url":"https://api.github.com/users/liangchenye/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liangchenye/subscriptions","organizations_url":"https://api.github.com/users/liangchenye/orgs","repos_url":"https://api.github.com/users/liangchenye/repos","events_url":"https://api.github.com/users/liangchenye/events{/privacy}","received_events_url":"https://api.github.com/users/liangchenye/received_events","type":"User","site_admin":false},"repo":{"id":46765486,"name":"ocitools","full_name":"liangchenye/ocitools","owner":{"login":"liangchenye","id":13341875,"avatar_url":"https://avatars.githubusercontent.com/u/13341875?v=3","gravatar_id":"","url":"https://api.github.com/users/liangchenye","html_url":"https://github.com/liangchenye","followers_url":"https://api.github.com/users/liangchenye/followers","following_url":"https://api.github.com/users/liangchenye/following{/other_user}","gists_url":"https://api.github.com/users/liangchenye/gists{/gist_id}","starred_url":"https://api.github.com/users/liangchenye/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liangchenye/subscriptions","organizations_url":"https://api.github.com/users/liangchenye/orgs","repos_url":"https://api.github.com/users/liangchenye/repos","events_url":"https://api.github.com/users/liangchenye/events{/privacy}","received_events_url":"https://api.github.com/users/liangchenye/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/liangchenye/ocitools","description":"Various tools for OCI ","fork":true,"url":"https://api.github.com/repos/liangchenye/ocitools","forks_url":"https://api.github.com/repos/liangchenye/ocitools/forks","keys_url":"https://api.github.com/repos/liangchenye/ocitools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/liangchenye/ocitools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/liangchenye/ocitools/teams","hooks_url":"https://api.github.com/repos/liangchenye/ocitools/hooks","issue_events_url":"https://api.github.com/repos/liangchenye/ocitools/issues/events{/number}","events_url":"https://api.github.com/repos/liangchenye/ocitools/events","assignees_url":"https://api.github.com/repos/liangchenye/ocitools/assignees{/user}","branches_url":"https://api.github.com/repos/liangchenye/ocitools/branches{/branch}","tags_url":"https://api.github.com/repos/liangchenye/ocitools/tags","blobs_url":"https://api.github.com/repos/liangchenye/ocitools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/liangchenye/ocitools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/liangchenye/ocitools/git/refs{/sha}","trees_url":"https://api.github.com/repos/liangchenye/ocitools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/liangchenye/ocitools/statuses/{sha}","languages_url":"https://api.github.com/repos/liangchenye/ocitools/languages","stargazers_url":"https://api.github.com/repos/liangchenye/ocitools/stargazers","contributors_url":"https://api.github.com/repos/liangchenye/ocitools/contributors","subscribers_url":"https://api.github.com/repos/liangchenye/ocitools/subscribers","subscription_url":"https://api.github.com/repos/liangchenye/ocitools/subscription","commits_url":"https://api.github.com/repos/liangchenye/ocitools/commits{/sha}","git_commits_url":"https://api.github.com/repos/liangchenye/ocitools/git/commits{/sha}","comments_url":"https://api.github.com/repos/liangchenye/ocitools/comments{/number}","issue_comment_url":"https://api.github.com/repos/liangchenye/ocitools/issues/comments{/number}","contents_url":"https://api.github.com/repos/liangchenye/ocitools/contents/{+path}","compare_url":"https://api.github.com/repos/liangchenye/ocitools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/liangchenye/ocitools/merges","archive_url":"https://api.github.com/repos/liangchenye/ocitools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/liangchenye/ocitools/downloads","issues_url":"https://api.github.com/repos/liangchenye/ocitools/issues{/number}","pulls_url":"https://api.github.com/repos/liangchenye/ocitools/pulls{/number}","milestones_url":"https://api.github.com/repos/liangchenye/ocitools/milestones{/number}","notifications_url":"https://api.github.com/repos/liangchenye/ocitools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/liangchenye/ocitools/labels{/name}","releases_url":"https://api.github.com/repos/liangchenye/ocitools/releases{/id}","created_at":"2015-11-24T03:51:34Z","updated_at":"2015-11-24T03:51:35Z","pushed_at":"2015-11-25T01:00:21Z","git_url":"git://github.com/liangchenye/ocitools.git","ssh_url":"git@github.com:liangchenye/ocitools.git","clone_url":"https://github.com/liangchenye/ocitools.git","svn_url":"https://github.com/liangchenye/ocitools","homepage":"","size":1480,"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":"mrunalp:master","ref":"master","sha":"b44ce7f8f91c9504c31234327cbc9fd538a9be7a","user":{"login":"mrunalp","id":53798,"avatar_url":"https://avatars.githubusercontent.com/u/53798?v=3","gravatar_id":"","url":"https://api.github.com/users/mrunalp","html_url":"https://github.com/mrunalp","followers_url":"https://api.github.com/users/mrunalp/followers","following_url":"https://api.github.com/users/mrunalp/following{/other_user}","gists_url":"https://api.github.com/users/mrunalp/gists{/gist_id}","starred_url":"https://api.github.com/users/mrunalp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrunalp/subscriptions","organizations_url":"https://api.github.com/users/mrunalp/orgs","repos_url":"https://api.github.com/users/mrunalp/repos","events_url":"https://api.github.com/users/mrunalp/events{/privacy}","received_events_url":"https://api.github.com/users/mrunalp/received_events","type":"User","site_admin":false},"repo":{"id":42551686,"name":"ocitools","full_name":"mrunalp/ocitools","owner":{"login":"mrunalp","id":53798,"avatar_url":"https://avatars.githubusercontent.com/u/53798?v=3","gravatar_id":"","url":"https://api.github.com/users/mrunalp","html_url":"https://github.com/mrunalp","followers_url":"https://api.github.com/users/mrunalp/followers","following_url":"https://api.github.com/users/mrunalp/following{/other_user}","gists_url":"https://api.github.com/users/mrunalp/gists{/gist_id}","starred_url":"https://api.github.com/users/mrunalp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrunalp/subscriptions","organizations_url":"https://api.github.com/users/mrunalp/orgs","repos_url":"https://api.github.com/users/mrunalp/repos","events_url":"https://api.github.com/users/mrunalp/events{/privacy}","received_events_url":"https://api.github.com/users/mrunalp/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mrunalp/ocitools","description":"Various tools for OCI ","fork":false,"url":"https://api.github.com/repos/mrunalp/ocitools","forks_url":"https://api.github.com/repos/mrunalp/ocitools/forks","keys_url":"https://api.github.com/repos/mrunalp/ocitools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mrunalp/ocitools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mrunalp/ocitools/teams","hooks_url":"https://api.github.com/repos/mrunalp/ocitools/hooks","issue_events_url":"https://api.github.com/repos/mrunalp/ocitools/issues/events{/number}","events_url":"https://api.github.com/repos/mrunalp/ocitools/events","assignees_url":"https://api.github.com/repos/mrunalp/ocitools/assignees{/user}","branches_url":"https://api.github.com/repos/mrunalp/ocitools/branches{/branch}","tags_url":"https://api.github.com/repos/mrunalp/ocitools/tags","blobs_url":"https://api.github.com/repos/mrunalp/ocitools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mrunalp/ocitools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mrunalp/ocitools/git/refs{/sha}","trees_url":"https://api.github.com/repos/mrunalp/ocitools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mrunalp/ocitools/statuses/{sha}","languages_url":"https://api.github.com/repos/mrunalp/ocitools/languages","stargazers_url":"https://api.github.com/repos/mrunalp/ocitools/stargazers","contributors_url":"https://api.github.com/repos/mrunalp/ocitools/contributors","subscribers_url":"https://api.github.com/repos/mrunalp/ocitools/subscribers","subscription_url":"https://api.github.com/repos/mrunalp/ocitools/subscription","commits_url":"https://api.github.com/repos/mrunalp/ocitools/commits{/sha}","git_commits_url":"https://api.github.com/repos/mrunalp/ocitools/git/commits{/sha}","comments_url":"https://api.github.com/repos/mrunalp/ocitools/comments{/number}","issue_comment_url":"https://api.github.com/repos/mrunalp/ocitools/issues/comments{/number}","contents_url":"https://api.github.com/repos/mrunalp/ocitools/contents/{+path}","compare_url":"https://api.github.com/repos/mrunalp/ocitools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mrunalp/ocitools/merges","archive_url":"https://api.github.com/repos/mrunalp/ocitools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mrunalp/ocitools/downloads","issues_url":"https://api.github.com/repos/mrunalp/ocitools/issues{/number}","pulls_url":"https://api.github.com/repos/mrunalp/ocitools/pulls{/number}","milestones_url":"https://api.github.com/repos/mrunalp/ocitools/milestones{/number}","notifications_url":"https://api.github.com/repos/mrunalp/ocitools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mrunalp/ocitools/labels{/name}","releases_url":"https://api.github.com/repos/mrunalp/ocitools/releases{/id}","created_at":"2015-09-15T22:57:57Z","updated_at":"2015-11-19T08:31:57Z","pushed_at":"2015-11-25T02:07:23Z","git_url":"git://github.com/mrunalp/ocitools.git","ssh_url":"git@github.com:mrunalp/ocitools.git","clone_url":"https://github.com/mrunalp/ocitools.git","svn_url":"https://github.com/mrunalp/ocitools","homepage":"","size":1485,"stargazers_count":4,"watchers_count":4,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":4,"forks":4,"open_issues":4,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mrunalp/ocitools/pulls/10"},"html":{"href":"https://github.com/mrunalp/ocitools/pull/10"},"issue":{"href":"https://api.github.com/repos/mrunalp/ocitools/issues/10"},"comments":{"href":"https://api.github.com/repos/mrunalp/ocitools/issues/10/comments"},"review_comments":{"href":"https://api.github.com/repos/mrunalp/ocitools/pulls/10/comments"},"review_comment":{"href":"https://api.github.com/repos/mrunalp/ocitools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mrunalp/ocitools/pulls/10/commits"},"statuses":{"href":"https://api.github.com/repos/mrunalp/ocitools/statuses/03949f93e22e7eeb6d81814e9fe5e68f9c35e210"}}}}