{"action":"created","comment":{"url":"https://api.github.com/repos/openshift/origin/pulls/comments/57768365","id":57768365,"diff_hunk":"@@ -120,26 +161,103 @@ func (bw *quotaRestrictedBlobWriter) Commit(ctx context.Context, provisional dis\n \treturn can, err\n }\n \n-// admitBlobWrite checks whether the blob does not exceed image quota, if set. Returns\n+// admitBlobWrite checks whether the blob does not exceed image quota or limit ranges, if set. Returns\n // ErrAccessDenied error if the quota is exceeded.\n-func admitBlobWrite(ctx context.Context, repo *repository) error {\n-\trqs, err := repo.quotaClient.ResourceQuotas(repo.namespace).List(kapi.ListOptions{})\n-\tif err != nil {\n-\t\tif kerrors.IsForbidden(err) {\n-\t\t\tcontext.GetLogger(ctx).Warnf(\"Cannot list resourcequotas because of outdated cluster roles: %v\", err)\n-\t\t\treturn nil\n-\t\t}\n-\t\tcontext.GetLogger(ctx).Errorf(\"Failed to list resourcequotas: %v\", err)\n+func admitBlobWrite(ctx context.Context, repo *repository, size int64) error {\n+\tif err := admitLimitRanges(ctx, repo, size); err != nil {\n+\t\treturn err\n+\t}\n+\n+\tif err := admitQuotas(ctx, repo); err != nil {\n \t\treturn err\n \t}\n \n+\treturn nil\n+}\n+\n+// admitLimitRanges checks the blob against any established limit ranges.\n+func admitLimitRanges(ctx context.Context, repo *repository, size int64) error {\n+\tif size < 1 {\n+\t\treturn nil\n+\t}\n+\n+\tvar (\n+\t\tlrs *kapi.LimitRangeList\n+\t\terr error\n+\t)\n+\n+\tif projectLimitRanges != nil {\n+\t\tobj, exists, _ := projectLimitRanges.Get(repo.namespace)\n+\t\tif exists {\n+\t\t\tlrs = obj.(*kapi.LimitRangeList)\n+\t\t}\n+\t}\n+\tif lrs == nil {\n+\t\tcontext.GetLogger(ctx).Debugf(\"Listing limit ranges in namespace %s\", repo.namespace)\n+\t\tlrs, err = repo.limitClient.LimitRanges(repo.namespace).List(kapi.ListOptions{})\n+\t\tif err != nil {","path":"pkg/dockerregistry/server/quotarestrictedblobstore.go","position":124,"original_position":124,"commit_id":"009f353ce0f5825f8e3821be026ae9f687ab66dc","original_commit_id":"009f353ce0f5825f8e3821be026ae9f687ab66dc","user":{"login":"deads2k","id":8225098,"avatar_url":"https://avatars.githubusercontent.com/u/8225098?v=3","gravatar_id":"","url":"https://api.github.com/users/deads2k","html_url":"https://github.com/deads2k","followers_url":"https://api.github.com/users/deads2k/followers","following_url":"https://api.github.com/users/deads2k/following{/other_user}","gists_url":"https://api.github.com/users/deads2k/gists{/gist_id}","starred_url":"https://api.github.com/users/deads2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deads2k/subscriptions","organizations_url":"https://api.github.com/users/deads2k/orgs","repos_url":"https://api.github.com/users/deads2k/repos","events_url":"https://api.github.com/users/deads2k/events{/privacy}","received_events_url":"https://api.github.com/users/deads2k/received_events","type":"User","site_admin":false},"body":"I think I'm misunderstanding what this is doing.  Aren't errors when getting `limitranges` and `resourcequotas` supposed to be ignored. ","created_at":"2016-03-29T17:52:15Z","updated_at":"2016-03-29T17:52:15Z","html_url":"https://github.com/openshift/origin/pull/8195#discussion_r57768365","pull_request_url":"https://api.github.com/repos/openshift/origin/pulls/8195","_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments/57768365"},"html":{"href":"https://github.com/openshift/origin/pull/8195#discussion_r57768365"},"pull_request":{"href":"https://api.github.com/repos/openshift/origin/pulls/8195"}}},"pull_request":{"url":"https://api.github.com/repos/openshift/origin/pulls/8195","id":63752628,"html_url":"https://github.com/openshift/origin/pull/8195","diff_url":"https://github.com/openshift/origin/pull/8195.diff","patch_url":"https://github.com/openshift/origin/pull/8195.patch","issue_url":"https://api.github.com/repos/openshift/origin/issues/8195","number":8195,"state":"open","locked":false,"title":"Refactor of image resource quota evaluators","user":{"login":"miminar","id":1478803,"avatar_url":"https://avatars.githubusercontent.com/u/1478803?v=3","gravatar_id":"","url":"https://api.github.com/users/miminar","html_url":"https://github.com/miminar","followers_url":"https://api.github.com/users/miminar/followers","following_url":"https://api.github.com/users/miminar/following{/other_user}","gists_url":"https://api.github.com/users/miminar/gists{/gist_id}","starred_url":"https://api.github.com/users/miminar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miminar/subscriptions","organizations_url":"https://api.github.com/users/miminar/orgs","repos_url":"https://api.github.com/users/miminar/repos","events_url":"https://api.github.com/users/miminar/events{/privacy}","received_events_url":"https://api.github.com/users/miminar/received_events","type":"User","site_admin":false},"body":"- Made image processing more readable.\r\n- Reduced number of queries to etcd.\r\n- Caching images in an expiring cache. The cache is shared within a registry\r\n  instance.\r\n- Ditched global variables.\r\n- Caching registry addresses in a lru cache. The cache is shared within a registry instance.\r\n- Using helpers to parse and create names of ImageStreamImages and ImageStreamTags.\r\n- Instantiate structs with a field names.\r\n- Added limit range admission checks limitting maximum image size.\r\n- Improved error reporting of failed builds.\r\n\r\n## TODO:\r\n\r\n- [ ] ~~share imagestream cache between all the admission plugins and resource controllers~~\r\n  - would require too big a change to the core\r\n- [x] `openshift.io/imagestreamimages` is a renamed `openshift.io/images` with almost the same semantics\r\n  - the difference is that all unique images tagged in a project are counted\r\n  - iow. no distinction is done between internally and externally managed images\r\n    - the purpose is a reduction of a number of queries to etcd\r\n- [x] `openshift.io/image-size` is a renamed `openshift.io/imagesize` with the same semantics\r\n  - this time, however, the admission is done only on `ImageStreamMapping` objects; we don't mind tagging such a pushed object to other image streams\r\n- [x] `openshift.io/imagestreamtags` is a new addition to quota resources\r\n  - it sets a limit on number of unique references (either internal or external) to images in the project\r\n  - specified by setting resource quota object\r\n- [x] The admission checks shall be done on `{CREATE} of ImageStreamImport`\r\n  - *Importing a repository has a max limit that is passed into the ISI registry from config - we'll need to pass that same max limit into the evaluator and treat an ISI as a +MAX. importing tags can be +N tags* \r\n- [x] relax precision on usage counting\r\n  - in the registry, cache quota and limit objecs in an expiring cache with at least 2 minute TTL\r\n  - this will highly reduce number of queries to etcd store during a push\r\n  - on the other hand, it will allow an abuser to push few images over the quota, but few images over the limit isn't such a big problem\r\n- [x] don't resolve `ImageStreamTags` and `DockerImage` references\r\n  - treat them automatically as +1 in `openshift.io/imagestreamimages` and `openshift.io/imagestreamtags`\r\n- [x] cache quota and limit range object in the registry during blob upload\r\n- [x] allow to disable quota enforcement in the registry\r\n  - add a flage to disable quote enforcement to the `oadm registry`\r\n  - pass env variable `OPENSHIFT_ENFORCE_QUOTA` to the registry\r\n  - by default, enforce quota in new deployment configs and don't enforce for the old ones\r\n- [x] fix extended tests\r\n","created_at":"2016-03-22T16:44:40Z","updated_at":"2016-03-29T17:52:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"236bd823f2693e81c3d3ed1b067fc857af3babd5","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/openshift/origin/pulls/8195/commits","review_comments_url":"https://api.github.com/repos/openshift/origin/pulls/8195/comments","review_comment_url":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openshift/origin/issues/8195/comments","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/009f353ce0f5825f8e3821be026ae9f687ab66dc","head":{"label":"miminar:registry-quota-refactor","ref":"registry-quota-refactor","sha":"009f353ce0f5825f8e3821be026ae9f687ab66dc","user":{"login":"miminar","id":1478803,"avatar_url":"https://avatars.githubusercontent.com/u/1478803?v=3","gravatar_id":"","url":"https://api.github.com/users/miminar","html_url":"https://github.com/miminar","followers_url":"https://api.github.com/users/miminar/followers","following_url":"https://api.github.com/users/miminar/following{/other_user}","gists_url":"https://api.github.com/users/miminar/gists{/gist_id}","starred_url":"https://api.github.com/users/miminar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miminar/subscriptions","organizations_url":"https://api.github.com/users/miminar/orgs","repos_url":"https://api.github.com/users/miminar/repos","events_url":"https://api.github.com/users/miminar/events{/privacy}","received_events_url":"https://api.github.com/users/miminar/received_events","type":"User","site_admin":false},"repo":{"id":36652057,"name":"origin","full_name":"miminar/origin","owner":{"login":"miminar","id":1478803,"avatar_url":"https://avatars.githubusercontent.com/u/1478803?v=3","gravatar_id":"","url":"https://api.github.com/users/miminar","html_url":"https://github.com/miminar","followers_url":"https://api.github.com/users/miminar/followers","following_url":"https://api.github.com/users/miminar/following{/other_user}","gists_url":"https://api.github.com/users/miminar/gists{/gist_id}","starred_url":"https://api.github.com/users/miminar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miminar/subscriptions","organizations_url":"https://api.github.com/users/miminar/orgs","repos_url":"https://api.github.com/users/miminar/repos","events_url":"https://api.github.com/users/miminar/events{/privacy}","received_events_url":"https://api.github.com/users/miminar/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/miminar/origin","description":"OpenShift 3 - build, deploy, and manage your applications with Docker and Kubernetes","fork":true,"url":"https://api.github.com/repos/miminar/origin","forks_url":"https://api.github.com/repos/miminar/origin/forks","keys_url":"https://api.github.com/repos/miminar/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/miminar/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/miminar/origin/teams","hooks_url":"https://api.github.com/repos/miminar/origin/hooks","issue_events_url":"https://api.github.com/repos/miminar/origin/issues/events{/number}","events_url":"https://api.github.com/repos/miminar/origin/events","assignees_url":"https://api.github.com/repos/miminar/origin/assignees{/user}","branches_url":"https://api.github.com/repos/miminar/origin/branches{/branch}","tags_url":"https://api.github.com/repos/miminar/origin/tags","blobs_url":"https://api.github.com/repos/miminar/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/miminar/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/miminar/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/miminar/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/miminar/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/miminar/origin/languages","stargazers_url":"https://api.github.com/repos/miminar/origin/stargazers","contributors_url":"https://api.github.com/repos/miminar/origin/contributors","subscribers_url":"https://api.github.com/repos/miminar/origin/subscribers","subscription_url":"https://api.github.com/repos/miminar/origin/subscription","commits_url":"https://api.github.com/repos/miminar/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/miminar/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/miminar/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/miminar/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/miminar/origin/contents/{+path}","compare_url":"https://api.github.com/repos/miminar/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/miminar/origin/merges","archive_url":"https://api.github.com/repos/miminar/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/miminar/origin/downloads","issues_url":"https://api.github.com/repos/miminar/origin/issues{/number}","pulls_url":"https://api.github.com/repos/miminar/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/miminar/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/miminar/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/miminar/origin/labels{/name}","releases_url":"https://api.github.com/repos/miminar/origin/releases{/id}","deployments_url":"https://api.github.com/repos/miminar/origin/deployments","created_at":"2015-06-01T09:53:10Z","updated_at":"2016-01-14T09:43:02Z","pushed_at":"2016-03-29T09:35:57Z","git_url":"git://github.com/miminar/origin.git","ssh_url":"git@github.com:miminar/origin.git","clone_url":"https://github.com/miminar/origin.git","svn_url":"https://github.com/miminar/origin","homepage":"http://www.openshift.org","size":231476,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"openshift:master","ref":"master","sha":"847f33723fe799c202a6bb6c24dc60b89294f80d","user":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"repo":{"id":22442668,"name":"origin","full_name":"openshift/origin","owner":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openshift/origin","description":"The Continuous Application Platform - build, deploy, and manage cloud-native and legacy applications on Kubernetes and Docker","fork":false,"url":"https://api.github.com/repos/openshift/origin","forks_url":"https://api.github.com/repos/openshift/origin/forks","keys_url":"https://api.github.com/repos/openshift/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openshift/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openshift/origin/teams","hooks_url":"https://api.github.com/repos/openshift/origin/hooks","issue_events_url":"https://api.github.com/repos/openshift/origin/issues/events{/number}","events_url":"https://api.github.com/repos/openshift/origin/events","assignees_url":"https://api.github.com/repos/openshift/origin/assignees{/user}","branches_url":"https://api.github.com/repos/openshift/origin/branches{/branch}","tags_url":"https://api.github.com/repos/openshift/origin/tags","blobs_url":"https://api.github.com/repos/openshift/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openshift/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openshift/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/openshift/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/openshift/origin/languages","stargazers_url":"https://api.github.com/repos/openshift/origin/stargazers","contributors_url":"https://api.github.com/repos/openshift/origin/contributors","subscribers_url":"https://api.github.com/repos/openshift/origin/subscribers","subscription_url":"https://api.github.com/repos/openshift/origin/subscription","commits_url":"https://api.github.com/repos/openshift/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/openshift/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/openshift/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/openshift/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/openshift/origin/contents/{+path}","compare_url":"https://api.github.com/repos/openshift/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openshift/origin/merges","archive_url":"https://api.github.com/repos/openshift/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openshift/origin/downloads","issues_url":"https://api.github.com/repos/openshift/origin/issues{/number}","pulls_url":"https://api.github.com/repos/openshift/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/openshift/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/openshift/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openshift/origin/labels{/name}","releases_url":"https://api.github.com/repos/openshift/origin/releases{/id}","deployments_url":"https://api.github.com/repos/openshift/origin/deployments","created_at":"2014-07-30T20:04:05Z","updated_at":"2016-03-29T16:41:57Z","pushed_at":"2016-03-29T17:21:27Z","git_url":"git://github.com/openshift/origin.git","ssh_url":"git@github.com:openshift/origin.git","clone_url":"https://github.com/openshift/origin.git","svn_url":"https://github.com/openshift/origin","homepage":"http://www.openshift.org","size":304414,"stargazers_count":1166,"watchers_count":1166,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":715,"mirror_url":null,"open_issues_count":969,"forks":715,"open_issues":969,"watchers":1166,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/8195"},"html":{"href":"https://github.com/openshift/origin/pull/8195"},"issue":{"href":"https://api.github.com/repos/openshift/origin/issues/8195"},"comments":{"href":"https://api.github.com/repos/openshift/origin/issues/8195/comments"},"review_comments":{"href":"https://api.github.com/repos/openshift/origin/pulls/8195/comments"},"review_comment":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openshift/origin/pulls/8195/commits"},"statuses":{"href":"https://api.github.com/repos/openshift/origin/statuses/009f353ce0f5825f8e3821be026ae9f687ab66dc"}}}}