{"action":"created","comment":{"url":"https://api.github.com/repos/habitat-sh/habitat/pulls/comments/133032104","pull_request_review_id":56115022,"id":133032104,"diff_hunk":"@@ -0,0 +1,275 @@\n+// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors\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+use std::collections::HashMap;\n+use std::result;\n+use std::str::FromStr;\n+\n+use hab_net::routing::Broker;\n+use protocol::originsrv::{CheckOriginAccessRequest, CheckOriginAccessResponse, Origin,\n+                          OriginChannel, OriginChannelCreate, OriginChannelGet, OriginGet,\n+                          OriginPackage, OriginPackageGet, OriginPackageGroupPromote,\n+                          OriginPackageIdent, OriginPackagePromote};\n+use protocol::net::{ErrCode, NetError, NetOk};\n+use protocol::scheduler::{Group, GroupGet, GroupState, Project, ProjectState};\n+use protocol::sessionsrv::{Session, SessionCreate, SessionGet};\n+\n+use data_structures::UnsuccessfulJobGroupPromote;\n+\n+use error::{Error, Result};\n+\n+pub fn get_origin<T: ToString>(origin: T) -> result::Result<Option<Origin>, NetError> {\n+    let mut conn = Broker::connect().unwrap();\n+    let mut request = OriginGet::new();\n+    request.set_name(origin.to_string());\n+\n+    match conn.route::<OriginGet, Origin>(&request) {\n+        Ok(origin) => Ok(Some(origin)),\n+        Err(err) => {\n+            if err.get_code() == ErrCode::ENTITY_NOT_FOUND {\n+                Ok(None)\n+            } else {\n+                Err(err)\n+            }\n+        }\n+    }\n+}\n+\n+pub fn check_origin_access<T: ToString>(\n+    account_id: u64,\n+    origin: T,\n+) -> result::Result<bool, NetError> {\n+    let mut conn = Broker::connect().unwrap();\n+    let mut request = CheckOriginAccessRequest::new();\n+    request.set_account_id(account_id);\n+    request.set_origin_name(origin.to_string());\n+    match conn.route::<CheckOriginAccessRequest, CheckOriginAccessResponse>(&request) {\n+        Ok(response) => Ok(response.get_has_access()),\n+        Err(err) => Err(err),\n+    }\n+}\n+\n+pub fn create_channel(origin: &str, channel: &str, session_id: u64) -> Result<(OriginChannel)> {\n+    let origin_id = match get_origin(origin).map_err(Error::NetError)? {\n+        Some(o) => o.get_id(),\n+        None => {\n+            debug!(\"Origin {} not found!\", origin);\n+            return Err(Error::OriginNotFound(origin.to_string()));\n+        }\n+    };\n+\n+    let mut conn = Broker::connect().unwrap();\n+    let mut request = OriginChannelCreate::new();\n+\n+    request.set_owner_id(session_id);\n+    request.set_origin_name(origin.to_string());\n+    request.set_origin_id(origin_id);\n+    request.set_name(channel.to_string());\n+\n+    match conn.route::<OriginChannelCreate, OriginChannel>(&request) {\n+        Ok(origin_channel) => Ok(origin_channel),\n+        Err(err) => Err(Error::NetError(err)),\n+    }\n+}\n+\n+pub fn promote_package_to_channel(\n+    ident: &OriginPackageIdent,\n+    channel: &str,\n+    session_id: u64,\n+) -> Result<()> {\n+    let mut conn = Broker::connect().unwrap();\n+    let mut channel_req = OriginChannelGet::new();\n+    channel_req.set_origin_name(ident.get_origin().to_string());\n+    channel_req.set_name(channel.to_string());\n+\n+    match conn.route::<OriginChannelGet, OriginChannel>(&channel_req) {\n+        Ok(origin_channel) => {\n+            if !check_origin_access(session_id, ident.get_origin())","path":"components/builder-core/src/api.rs","position":98,"original_position":98,"commit_id":"ec9ed5cd7c22e8caa13fa0097c5bd5d84f6db14f","original_commit_id":"ec9ed5cd7c22e8caa13fa0097c5bd5d84f6db14f","user":{"login":"christophermaier","id":207178,"avatar_url":"https://avatars2.githubusercontent.com/u/207178?v=4","gravatar_id":"","url":"https://api.github.com/users/christophermaier","html_url":"https://github.com/christophermaier","followers_url":"https://api.github.com/users/christophermaier/followers","following_url":"https://api.github.com/users/christophermaier/following{/other_user}","gists_url":"https://api.github.com/users/christophermaier/gists{/gist_id}","starred_url":"https://api.github.com/users/christophermaier/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/christophermaier/subscriptions","organizations_url":"https://api.github.com/users/christophermaier/orgs","repos_url":"https://api.github.com/users/christophermaier/repos","events_url":"https://api.github.com/users/christophermaier/events{/privacy}","received_events_url":"https://api.github.com/users/christophermaier/received_events","type":"User","site_admin":false},"body":"Better to check this before making unnecessary network requests.","created_at":"2017-08-14T18:55:13Z","updated_at":"2017-08-14T19:00:37Z","html_url":"https://github.com/habitat-sh/habitat/pull/2866#discussion_r133032104","pull_request_url":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866","_links":{"self":{"href":"https://api.github.com/repos/habitat-sh/habitat/pulls/comments/133032104"},"html":{"href":"https://github.com/habitat-sh/habitat/pull/2866#discussion_r133032104"},"pull_request":{"href":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866"}}},"pull_request":{"url":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866","id":134033317,"html_url":"https://github.com/habitat-sh/habitat/pull/2866","diff_url":"https://github.com/habitat-sh/habitat/pull/2866.diff","patch_url":"https://github.com/habitat-sh/habitat/pull/2866.patch","issue_url":"https://api.github.com/repos/habitat-sh/habitat/issues/2866","number":2866,"state":"open","locked":false,"title":"Implement \"hab job promote\"","user":{"login":"raskchanky","id":947,"avatar_url":"https://avatars1.githubusercontent.com/u/947?v=4","gravatar_id":"","url":"https://api.github.com/users/raskchanky","html_url":"https://github.com/raskchanky","followers_url":"https://api.github.com/users/raskchanky/followers","following_url":"https://api.github.com/users/raskchanky/following{/other_user}","gists_url":"https://api.github.com/users/raskchanky/gists{/gist_id}","starred_url":"https://api.github.com/users/raskchanky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raskchanky/subscriptions","organizations_url":"https://api.github.com/users/raskchanky/orgs","repos_url":"https://api.github.com/users/raskchanky/repos","events_url":"https://api.github.com/users/raskchanky/events{/privacy}","received_events_url":"https://api.github.com/users/raskchanky/received_events","type":"User","site_admin":false},"body":"This introduces the `hab job promote` command, which gives the ability to take a job group ID and a channel name and promote every successfully built project inside that job group to the specified channel.\r\n\r\nPart of this change is a new API endpoint in `builder-api` which does this promotion in one shot, instead of requiring N+1 HTTP requests for individually promoting every successfully built project inside a job group.  `builder-scheduler` was refactored to utilize this new endpoint.  Further optimizations to `builder-scheduler` are still possible, to completely remove the need to use HTTP for communicating between services, but I didn't touch any of that here.\r\n\r\n![tenor-51992790](https://user-images.githubusercontent.com/947/28941816-12114b78-784e-11e7-9cac-2be8e4bcef17.gif)","created_at":"2017-08-03T20:23:15Z","updated_at":"2017-08-14T19:00:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5d6f846bfac3188ecb9fb024e16aa0b01ec29722","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866/commits","review_comments_url":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866/comments","review_comment_url":"https://api.github.com/repos/habitat-sh/habitat/pulls/comments{/number}","comments_url":"https://api.github.com/repos/habitat-sh/habitat/issues/2866/comments","statuses_url":"https://api.github.com/repos/habitat-sh/habitat/statuses/ec9ed5cd7c22e8caa13fa0097c5bd5d84f6db14f","head":{"label":"habitat-sh:jb/hab-job-promote","ref":"jb/hab-job-promote","sha":"ec9ed5cd7c22e8caa13fa0097c5bd5d84f6db14f","user":{"login":"habitat-sh","id":18171698,"avatar_url":"https://avatars0.githubusercontent.com/u/18171698?v=4","gravatar_id":"","url":"https://api.github.com/users/habitat-sh","html_url":"https://github.com/habitat-sh","followers_url":"https://api.github.com/users/habitat-sh/followers","following_url":"https://api.github.com/users/habitat-sh/following{/other_user}","gists_url":"https://api.github.com/users/habitat-sh/gists{/gist_id}","starred_url":"https://api.github.com/users/habitat-sh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/habitat-sh/subscriptions","organizations_url":"https://api.github.com/users/habitat-sh/orgs","repos_url":"https://api.github.com/users/habitat-sh/repos","events_url":"https://api.github.com/users/habitat-sh/events{/privacy}","received_events_url":"https://api.github.com/users/habitat-sh/received_events","type":"Organization","site_admin":false},"repo":{"id":36098429,"name":"habitat","full_name":"habitat-sh/habitat","owner":{"login":"habitat-sh","id":18171698,"avatar_url":"https://avatars0.githubusercontent.com/u/18171698?v=4","gravatar_id":"","url":"https://api.github.com/users/habitat-sh","html_url":"https://github.com/habitat-sh","followers_url":"https://api.github.com/users/habitat-sh/followers","following_url":"https://api.github.com/users/habitat-sh/following{/other_user}","gists_url":"https://api.github.com/users/habitat-sh/gists{/gist_id}","starred_url":"https://api.github.com/users/habitat-sh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/habitat-sh/subscriptions","organizations_url":"https://api.github.com/users/habitat-sh/orgs","repos_url":"https://api.github.com/users/habitat-sh/repos","events_url":"https://api.github.com/users/habitat-sh/events{/privacy}","received_events_url":"https://api.github.com/users/habitat-sh/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/habitat-sh/habitat","description":"Modern applications with built-in automation","fork":false,"url":"https://api.github.com/repos/habitat-sh/habitat","forks_url":"https://api.github.com/repos/habitat-sh/habitat/forks","keys_url":"https://api.github.com/repos/habitat-sh/habitat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/habitat-sh/habitat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/habitat-sh/habitat/teams","hooks_url":"https://api.github.com/repos/habitat-sh/habitat/hooks","issue_events_url":"https://api.github.com/repos/habitat-sh/habitat/issues/events{/number}","events_url":"https://api.github.com/repos/habitat-sh/habitat/events","assignees_url":"https://api.github.com/repos/habitat-sh/habitat/assignees{/user}","branches_url":"https://api.github.com/repos/habitat-sh/habitat/branches{/branch}","tags_url":"https://api.github.com/repos/habitat-sh/habitat/tags","blobs_url":"https://api.github.com/repos/habitat-sh/habitat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/habitat-sh/habitat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/habitat-sh/habitat/git/refs{/sha}","trees_url":"https://api.github.com/repos/habitat-sh/habitat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/habitat-sh/habitat/statuses/{sha}","languages_url":"https://api.github.com/repos/habitat-sh/habitat/languages","stargazers_url":"https://api.github.com/repos/habitat-sh/habitat/stargazers","contributors_url":"https://api.github.com/repos/habitat-sh/habitat/contributors","subscribers_url":"https://api.github.com/repos/habitat-sh/habitat/subscribers","subscription_url":"https://api.github.com/repos/habitat-sh/habitat/subscription","commits_url":"https://api.github.com/repos/habitat-sh/habitat/commits{/sha}","git_commits_url":"https://api.github.com/repos/habitat-sh/habitat/git/commits{/sha}","comments_url":"https://api.github.com/repos/habitat-sh/habitat/comments{/number}","issue_comment_url":"https://api.github.com/repos/habitat-sh/habitat/issues/comments{/number}","contents_url":"https://api.github.com/repos/habitat-sh/habitat/contents/{+path}","compare_url":"https://api.github.com/repos/habitat-sh/habitat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/habitat-sh/habitat/merges","archive_url":"https://api.github.com/repos/habitat-sh/habitat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/habitat-sh/habitat/downloads","issues_url":"https://api.github.com/repos/habitat-sh/habitat/issues{/number}","pulls_url":"https://api.github.com/repos/habitat-sh/habitat/pulls{/number}","milestones_url":"https://api.github.com/repos/habitat-sh/habitat/milestones{/number}","notifications_url":"https://api.github.com/repos/habitat-sh/habitat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/habitat-sh/habitat/labels{/name}","releases_url":"https://api.github.com/repos/habitat-sh/habitat/releases{/id}","deployments_url":"https://api.github.com/repos/habitat-sh/habitat/deployments","created_at":"2015-05-22T22:47:14Z","updated_at":"2017-08-13T20:01:18Z","pushed_at":"2017-08-14T18:56:55Z","git_url":"git://github.com/habitat-sh/habitat.git","ssh_url":"git@github.com:habitat-sh/habitat.git","clone_url":"https://github.com/habitat-sh/habitat.git","svn_url":"https://github.com/habitat-sh/habitat","homepage":"https://www.habitat.sh","size":57667,"stargazers_count":1170,"watchers_count":1170,"language":"Rust","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":177,"mirror_url":null,"open_issues_count":245,"forks":177,"open_issues":245,"watchers":1170,"default_branch":"master"}},"base":{"label":"habitat-sh:master","ref":"master","sha":"40c99da410847eaec4aa9623ddb062db7277005d","user":{"login":"habitat-sh","id":18171698,"avatar_url":"https://avatars0.githubusercontent.com/u/18171698?v=4","gravatar_id":"","url":"https://api.github.com/users/habitat-sh","html_url":"https://github.com/habitat-sh","followers_url":"https://api.github.com/users/habitat-sh/followers","following_url":"https://api.github.com/users/habitat-sh/following{/other_user}","gists_url":"https://api.github.com/users/habitat-sh/gists{/gist_id}","starred_url":"https://api.github.com/users/habitat-sh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/habitat-sh/subscriptions","organizations_url":"https://api.github.com/users/habitat-sh/orgs","repos_url":"https://api.github.com/users/habitat-sh/repos","events_url":"https://api.github.com/users/habitat-sh/events{/privacy}","received_events_url":"https://api.github.com/users/habitat-sh/received_events","type":"Organization","site_admin":false},"repo":{"id":36098429,"name":"habitat","full_name":"habitat-sh/habitat","owner":{"login":"habitat-sh","id":18171698,"avatar_url":"https://avatars0.githubusercontent.com/u/18171698?v=4","gravatar_id":"","url":"https://api.github.com/users/habitat-sh","html_url":"https://github.com/habitat-sh","followers_url":"https://api.github.com/users/habitat-sh/followers","following_url":"https://api.github.com/users/habitat-sh/following{/other_user}","gists_url":"https://api.github.com/users/habitat-sh/gists{/gist_id}","starred_url":"https://api.github.com/users/habitat-sh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/habitat-sh/subscriptions","organizations_url":"https://api.github.com/users/habitat-sh/orgs","repos_url":"https://api.github.com/users/habitat-sh/repos","events_url":"https://api.github.com/users/habitat-sh/events{/privacy}","received_events_url":"https://api.github.com/users/habitat-sh/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/habitat-sh/habitat","description":"Modern applications with built-in automation","fork":false,"url":"https://api.github.com/repos/habitat-sh/habitat","forks_url":"https://api.github.com/repos/habitat-sh/habitat/forks","keys_url":"https://api.github.com/repos/habitat-sh/habitat/keys{/key_id}","collaborators_url":"https://api.github.com/repos/habitat-sh/habitat/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/habitat-sh/habitat/teams","hooks_url":"https://api.github.com/repos/habitat-sh/habitat/hooks","issue_events_url":"https://api.github.com/repos/habitat-sh/habitat/issues/events{/number}","events_url":"https://api.github.com/repos/habitat-sh/habitat/events","assignees_url":"https://api.github.com/repos/habitat-sh/habitat/assignees{/user}","branches_url":"https://api.github.com/repos/habitat-sh/habitat/branches{/branch}","tags_url":"https://api.github.com/repos/habitat-sh/habitat/tags","blobs_url":"https://api.github.com/repos/habitat-sh/habitat/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/habitat-sh/habitat/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/habitat-sh/habitat/git/refs{/sha}","trees_url":"https://api.github.com/repos/habitat-sh/habitat/git/trees{/sha}","statuses_url":"https://api.github.com/repos/habitat-sh/habitat/statuses/{sha}","languages_url":"https://api.github.com/repos/habitat-sh/habitat/languages","stargazers_url":"https://api.github.com/repos/habitat-sh/habitat/stargazers","contributors_url":"https://api.github.com/repos/habitat-sh/habitat/contributors","subscribers_url":"https://api.github.com/repos/habitat-sh/habitat/subscribers","subscription_url":"https://api.github.com/repos/habitat-sh/habitat/subscription","commits_url":"https://api.github.com/repos/habitat-sh/habitat/commits{/sha}","git_commits_url":"https://api.github.com/repos/habitat-sh/habitat/git/commits{/sha}","comments_url":"https://api.github.com/repos/habitat-sh/habitat/comments{/number}","issue_comment_url":"https://api.github.com/repos/habitat-sh/habitat/issues/comments{/number}","contents_url":"https://api.github.com/repos/habitat-sh/habitat/contents/{+path}","compare_url":"https://api.github.com/repos/habitat-sh/habitat/compare/{base}...{head}","merges_url":"https://api.github.com/repos/habitat-sh/habitat/merges","archive_url":"https://api.github.com/repos/habitat-sh/habitat/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/habitat-sh/habitat/downloads","issues_url":"https://api.github.com/repos/habitat-sh/habitat/issues{/number}","pulls_url":"https://api.github.com/repos/habitat-sh/habitat/pulls{/number}","milestones_url":"https://api.github.com/repos/habitat-sh/habitat/milestones{/number}","notifications_url":"https://api.github.com/repos/habitat-sh/habitat/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/habitat-sh/habitat/labels{/name}","releases_url":"https://api.github.com/repos/habitat-sh/habitat/releases{/id}","deployments_url":"https://api.github.com/repos/habitat-sh/habitat/deployments","created_at":"2015-05-22T22:47:14Z","updated_at":"2017-08-13T20:01:18Z","pushed_at":"2017-08-14T18:56:55Z","git_url":"git://github.com/habitat-sh/habitat.git","ssh_url":"git@github.com:habitat-sh/habitat.git","clone_url":"https://github.com/habitat-sh/habitat.git","svn_url":"https://github.com/habitat-sh/habitat","homepage":"https://www.habitat.sh","size":57667,"stargazers_count":1170,"watchers_count":1170,"language":"Rust","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":177,"mirror_url":null,"open_issues_count":245,"forks":177,"open_issues":245,"watchers":1170,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866"},"html":{"href":"https://github.com/habitat-sh/habitat/pull/2866"},"issue":{"href":"https://api.github.com/repos/habitat-sh/habitat/issues/2866"},"comments":{"href":"https://api.github.com/repos/habitat-sh/habitat/issues/2866/comments"},"review_comments":{"href":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866/comments"},"review_comment":{"href":"https://api.github.com/repos/habitat-sh/habitat/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/habitat-sh/habitat/pulls/2866/commits"},"statuses":{"href":"https://api.github.com/repos/habitat-sh/habitat/statuses/ec9ed5cd7c22e8caa13fa0097c5bd5d84f6db14f"}}}}
{"actor":{"display_login":"christophermaier"}}