{"action":"created","comment":{"url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/comments/34870499","id":34870499,"diff_hunk":"@@ -0,0 +1,422 @@\n+var _ = require('lodash');\n+var async = require('async');\n+var util = require('util');\n+\n+var Fleetctl = require('fleetctl/fleetctl');\n+var executor = require('fleetctl/lib/executor');\n+var utils = require('fleetctl/lib/utils');\n+\n+Fleetctl.prototype.cat = function(unitfile, fn){\n+  executor.execute(this.binary, utils.obj_to_kv(this.options), 'cat ' + unitfile, fn);\n+};\n+\n+var Launchpad = function(config){\n+  this.config = _.defaults(config || {}, {\n+    logger: null,\n+    fleet_endpoint: 'http://172.17.42.1:4001',\n+    restart_check_wait_timeout: 5000\n+  });\n+\n+  this.fleetctl = new Fleetctl({\n+    endpoint: this.config.fleet_endpoint\n+  });\n+};\n+\n+/**\n+ * Run the update strategy chain.\n+ */\n+Launchpad.prototype.runUpdateStrategy = function(image, strategy, cb){\n+  var that = this;\n+\n+  that.config.logger.info({image: image, strategy: strategy}, 'Updating services.');\n+\n+  async.waterfall([\n+    // Get unit files from fleetctl.\n+    function(wf_cb){\n+      that.fleetctl.list_unit_files(wf_cb);\n+    },\n+    // Filter for global or template unitfiles.\n+    function(unitfiles, wf_cb){\n+      var mainUnitfiles = _.filter(unitfiles, function(unitfile){\n+        return that.isUnitGlobal(unitfile.unit) || that.isUnitTemplate(unitfile.unit);\n+      });\n+\n+      return wf_cb(null, mainUnitfiles);\n+    },\n+    // Parse unit file and detect docker image settings.\n+    function(mainUnitfiles, wf_cb){\n+      var parseDockerInfo = function(service){\n+        var nameMatch = /Environment=DOCKER_IMAGE_NAME=(.*)/m.exec(service);\n+        var tagMatch = /Environment=DOCKER_IMAGE_TAG=(.*)/m.exec(service);\n+\n+        var info = {\n+          docker_image_name: nameMatch ? nameMatch[1] : null,\n+          docker_image_tag: tagMatch ? tagMatch[1] : null\n+        };\n+\n+        return info;\n+      };\n+\n+      async.map(mainUnitfiles, function(unitfile, async_cb){\n+        that.fleetctl.cat(unitfile.unit, function(err, cat) {\n+          if (err) {\n+            return async_cb(err);\n+          }\n+\n+          var dockerInfo = parseDockerInfo(cat);\n+\n+          if (dockerInfo.docker_image_name) {\n+            dockerInfo.unitfile = unitfile.unit;\n+            dockerInfo.global = that.isUnitGlobal(unitfile.unit);\n+            return async_cb(null, dockerInfo);\n+          }\n+\n+          return async_cb(null, null);\n+        });\n+      }, wf_cb);\n+    },\n+    // Remove units without docker information.\n+    function(filteredUnitfiles, wf_cb){\n+      var validUnits = _.filter(filteredUnitfiles, function(unit){\n+        return unit;\n+      });\n+\n+      return wf_cb(null, validUnits);\n+    },\n+    // Detect units matching the docker image.\n+    function(validUnits, wf_cb){\n+      var matchingUnits = _.filter(validUnits, function(unit){\n+        return unit.docker_image_name === image;\n+      });\n+\n+      if (matchingUnits.length) {\n+        that.config.logger.info({image: image, matching_units: matchingUnits}, 'Identified units.');\n+        return wf_cb(null, matchingUnits);\n+      }\n+      else {\n+        that.config.logger.warn({image: image}, 'No matching units.');\n+        return wf_cb(new Error(util.format('No matching units for image: %s', image)));\n+      }\n+    },\n+    // Get old units matching the unitfile.\n+    function(matchingUnits, wf_cb){\n+      that.fleetctl.list_units(function(err, units) {\n+        if (err) {\n+          return wf_cb(err);\n+        }\n+\n+        matchingUnits = _.map(matchingUnits, function(matchingUnit){\n+          matchingUnit.prefix = matchingUnit.unitfile.split('.')[0];\n+\n+          // Match old units running this unit file.\n+          matchingUnit.instances = _.filter(units, function(unit){\n+            return unit.unit.indexOf(matchingUnit.prefix) !== -1 && unit.active === 'active';\n+          });\n+\n+          return matchingUnit;\n+        });\n+\n+        // @TODO: allow multiple matches!!!\n+        var oldUnits = matchingUnits[0].instances;\n+\n+        return wf_cb(null, oldUnits, matchingUnits[0].prefix);\n+      });\n+    },\n+    // Run update strategy.\n+    function(oldUnits, prefix, wf_cb){\n+      if (that.isUnitGlobal(prefix)) {\n+        strategy = 'global';\n+      }\n+\n+      that.config.logger.info({strategy: strategy, units: oldUnits}, 'Apply strategy.');\n+\n+      switch (strategy) {\n+      case 'global':\n+        return that.strategyGlobal(oldUnits, wf_cb);\n+        break;\n+      case 'replace':\n+        return that.strategyReplace(oldUnits, wf_cb);\n+        break;\n+      case 'rolling':\n+        return that.strategyRolling(oldUnits, prefix, wf_cb);\n+        break;\n+      default:\n+        that.config.logger.error({strategy: strategy}, 'Invalid strategy.');\n+        return wf_cb(new Error('Invalid strategy: ' + strategy));\n+        break;\n+      }\n+    }\n+  ], cb);\n+};\n+\n+/**\n+ * Update strategy `replace`.\n+ * Stops/starts one unit after another.\n+ *\n+ * Example:\n+ * [1][1][1]\n+ * [0][1][1]\n+ * [1][1][1]\n+ * [1][0][1]\n+ * [1][1][1]\n+ * [1][1][0]\n+ * [1][1][1]\n+ */\n+Launchpad.prototype.strategyReplace = function(oldUnits, cb){\n+  var that = this;\n+\n+  async.eachSeries(oldUnits, function(unit, async_cb){\n+    that.config.logger.info({unit: unit}, 'Restarting unit.');\n+\n+    async.waterfall([\n+      // Stop existing unit.\n+      function(wf_cb){\n+        that.config.logger.info({unit: unit}, 'Stopping unit.');\n+\n+        that.fleetctl.stop(unit.unit, function(err, data) {\n+          if (err) {\n+            return wf_cb(err);\n+          }\n+\n+          return wf_cb(null);\n+        });\n+      },\n+      // Start existing unit.\n+      function(wf_cb){\n+        that.config.logger.info({unit: unit}, 'Starting unit.');\n+\n+        that.fleetctl.start(unit.unit, function(err, data) {\n+          if (err) {\n+            return wf_cb(err);\n+          }\n+\n+          return wf_cb(null);\n+        });\n+      },\n+      // Wait for unit to come up.\n+      function(wf_cb){\n+        that.config.logger.info({unit: unit}, 'Waiting for unit.');\n+\n+        var checkRunningUnits = function(){\n+          that.fleetctl.list_units(function(err, units) {\n+            var matchingUnit = _.find(units, {unit: unit.unit, active: 'active'});\n+\n+            if (matchingUnit) {\n+              that.config.logger.info({unit: unit}, 'Unit running.');\n+\n+              return wf_cb(null);\n+            }\n+            else {\n+              setTimeout(function(){\n+                checkRunningUnits();\n+              }, that.config.restart_check_wait_timeout);\n+            }\n+          });\n+        };\n+\n+        checkRunningUnits();\n+      }\n+    ], async_cb);\n+  }, function(err){\n+    that.config.logger.info({units: oldUnits}, 'Restarted template units.');\n+    var message = util.format('Restarted template units: %s', _.pluck(oldUnits, 'unit'));\n+    return cb(err, message);\n+  });\n+};\n+\n+/**\n+ * Update strategy `rolling`.\n+ * Creates the same amount of new containers and then destroy the old ones.\n+ *\n+ * Example:\n+ * [1][1][1]\n+ * [1][1][1][0][0][0]\n+ * [1][1][1][1][1][1]\n+ * [0][0][0][1][1][1]\n+ *          [1][1][1]\n+ */\n+Launchpad.prototype.strategyRolling = function(oldUnits, prefix, cb){\n+  var that = this;\n+\n+  async.waterfall([\n+    // Prepare new units.\n+    function(wf_cb){\n+      var oldUnitCount = oldUnits.length;\n+\n+      // Get highest unit number.\n+      var unitNumberMax = 0;\n+      oldUnits.forEach(function(unit){\n+        var unitNumber = that.getUnitNumber(unit.unit);\n+        if (unitNumber > unitNumberMax) {\n+          unitNumberMax = parseInt(unitNumber, 10);\n+        }\n+      });\n+\n+      var newUnits = [];\n+      for (var i = 1; i <= oldUnitCount; i++) {\n+        var unitNumber = unitNumberMax + i;\n+        newUnits.push(prefix + unitNumber);\n+      }\n+","path":"lib/launchpad.js","position":260,"original_position":260,"commit_id":"27116d8ea84239f8c2c63992b12c699c16503d3d","original_commit_id":"27116d8ea84239f8c2c63992b12c699c16503d3d","user":{"login":"xoss","id":1513433,"avatar_url":"https://avatars.githubusercontent.com/u/1513433?v=3","gravatar_id":"","url":"https://api.github.com/users/xoss","html_url":"https://github.com/xoss","followers_url":"https://api.github.com/users/xoss/followers","following_url":"https://api.github.com/users/xoss/following{/other_user}","gists_url":"https://api.github.com/users/xoss/gists{/gist_id}","starred_url":"https://api.github.com/users/xoss/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xoss/subscriptions","organizations_url":"https://api.github.com/users/xoss/orgs","repos_url":"https://api.github.com/users/xoss/repos","events_url":"https://api.github.com/users/xoss/events{/privacy}","received_events_url":"https://api.github.com/users/xoss/received_events","type":"User","site_admin":false},"body":"```js\r\nvar newUnits = _.map(_.range(unitNumberMax + 1, oldUnitCount), function (unitNumber) {\r\n  return prefix + unitNumber\r\n});","created_at":"2015-07-17T08:22:49Z","updated_at":"2015-07-17T08:22:49Z","html_url":"https://github.com/Organiceme/docker-launchpad/pull/1#discussion_r34870499","pull_request_url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/comments/34870499"},"html":{"href":"https://github.com/Organiceme/docker-launchpad/pull/1#discussion_r34870499"},"pull_request":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1","id":39494577,"html_url":"https://github.com/Organiceme/docker-launchpad/pull/1","diff_url":"https://github.com/Organiceme/docker-launchpad/pull/1.diff","patch_url":"https://github.com/Organiceme/docker-launchpad/pull/1.patch","issue_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/1","number":1,"state":"open","locked":false,"title":"Feature ar 4098 continuous deployment","user":{"login":"bkonetzny","id":5451122,"avatar_url":"https://avatars.githubusercontent.com/u/5451122?v=3","gravatar_id":"","url":"https://api.github.com/users/bkonetzny","html_url":"https://github.com/bkonetzny","followers_url":"https://api.github.com/users/bkonetzny/followers","following_url":"https://api.github.com/users/bkonetzny/following{/other_user}","gists_url":"https://api.github.com/users/bkonetzny/gists{/gist_id}","starred_url":"https://api.github.com/users/bkonetzny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bkonetzny/subscriptions","organizations_url":"https://api.github.com/users/bkonetzny/orgs","repos_url":"https://api.github.com/users/bkonetzny/repos","events_url":"https://api.github.com/users/bkonetzny/events{/privacy}","received_events_url":"https://api.github.com/users/bkonetzny/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-07-08T16:09:31Z","updated_at":"2015-07-17T08:22:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b63200cb2af53d1854a6290d94b47f306bf8b8bb","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1/commits","review_comments_url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1/comments","review_comment_url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/1/comments","statuses_url":"https://api.github.com/repos/Organiceme/docker-launchpad/statuses/27116d8ea84239f8c2c63992b12c699c16503d3d","head":{"label":"Organiceme:feature-AR-4098-continuous-deployment","ref":"feature-AR-4098-continuous-deployment","sha":"27116d8ea84239f8c2c63992b12c699c16503d3d","user":{"login":"Organiceme","id":4245628,"avatar_url":"https://avatars.githubusercontent.com/u/4245628?v=3","gravatar_id":"","url":"https://api.github.com/users/Organiceme","html_url":"https://github.com/Organiceme","followers_url":"https://api.github.com/users/Organiceme/followers","following_url":"https://api.github.com/users/Organiceme/following{/other_user}","gists_url":"https://api.github.com/users/Organiceme/gists{/gist_id}","starred_url":"https://api.github.com/users/Organiceme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Organiceme/subscriptions","organizations_url":"https://api.github.com/users/Organiceme/orgs","repos_url":"https://api.github.com/users/Organiceme/repos","events_url":"https://api.github.com/users/Organiceme/events{/privacy}","received_events_url":"https://api.github.com/users/Organiceme/received_events","type":"Organization","site_admin":false},"repo":{"id":38761172,"name":"docker-launchpad","full_name":"Organiceme/docker-launchpad","owner":{"login":"Organiceme","id":4245628,"avatar_url":"https://avatars.githubusercontent.com/u/4245628?v=3","gravatar_id":"","url":"https://api.github.com/users/Organiceme","html_url":"https://github.com/Organiceme","followers_url":"https://api.github.com/users/Organiceme/followers","following_url":"https://api.github.com/users/Organiceme/following{/other_user}","gists_url":"https://api.github.com/users/Organiceme/gists{/gist_id}","starred_url":"https://api.github.com/users/Organiceme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Organiceme/subscriptions","organizations_url":"https://api.github.com/users/Organiceme/orgs","repos_url":"https://api.github.com/users/Organiceme/repos","events_url":"https://api.github.com/users/Organiceme/events{/privacy}","received_events_url":"https://api.github.com/users/Organiceme/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Organiceme/docker-launchpad","description":"Launchpad container for continuous deployment","fork":false,"url":"https://api.github.com/repos/Organiceme/docker-launchpad","forks_url":"https://api.github.com/repos/Organiceme/docker-launchpad/forks","keys_url":"https://api.github.com/repos/Organiceme/docker-launchpad/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Organiceme/docker-launchpad/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Organiceme/docker-launchpad/teams","hooks_url":"https://api.github.com/repos/Organiceme/docker-launchpad/hooks","issue_events_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/events{/number}","events_url":"https://api.github.com/repos/Organiceme/docker-launchpad/events","assignees_url":"https://api.github.com/repos/Organiceme/docker-launchpad/assignees{/user}","branches_url":"https://api.github.com/repos/Organiceme/docker-launchpad/branches{/branch}","tags_url":"https://api.github.com/repos/Organiceme/docker-launchpad/tags","blobs_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/refs{/sha}","trees_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Organiceme/docker-launchpad/statuses/{sha}","languages_url":"https://api.github.com/repos/Organiceme/docker-launchpad/languages","stargazers_url":"https://api.github.com/repos/Organiceme/docker-launchpad/stargazers","contributors_url":"https://api.github.com/repos/Organiceme/docker-launchpad/contributors","subscribers_url":"https://api.github.com/repos/Organiceme/docker-launchpad/subscribers","subscription_url":"https://api.github.com/repos/Organiceme/docker-launchpad/subscription","commits_url":"https://api.github.com/repos/Organiceme/docker-launchpad/commits{/sha}","git_commits_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/commits{/sha}","comments_url":"https://api.github.com/repos/Organiceme/docker-launchpad/comments{/number}","issue_comment_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/comments{/number}","contents_url":"https://api.github.com/repos/Organiceme/docker-launchpad/contents/{+path}","compare_url":"https://api.github.com/repos/Organiceme/docker-launchpad/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Organiceme/docker-launchpad/merges","archive_url":"https://api.github.com/repos/Organiceme/docker-launchpad/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Organiceme/docker-launchpad/downloads","issues_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues{/number}","pulls_url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls{/number}","milestones_url":"https://api.github.com/repos/Organiceme/docker-launchpad/milestones{/number}","notifications_url":"https://api.github.com/repos/Organiceme/docker-launchpad/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Organiceme/docker-launchpad/labels{/name}","releases_url":"https://api.github.com/repos/Organiceme/docker-launchpad/releases{/id}","created_at":"2015-07-08T15:00:21Z","updated_at":"2015-07-14T07:50:25Z","pushed_at":"2015-07-13T14:56:19Z","git_url":"git://github.com/Organiceme/docker-launchpad.git","ssh_url":"git@github.com:Organiceme/docker-launchpad.git","clone_url":"https://github.com/Organiceme/docker-launchpad.git","svn_url":"https://github.com/Organiceme/docker-launchpad","homepage":"","size":152,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"Organiceme:master","ref":"master","sha":"98c99f02e50234f57a8597c54ce0e247cabe3437","user":{"login":"Organiceme","id":4245628,"avatar_url":"https://avatars.githubusercontent.com/u/4245628?v=3","gravatar_id":"","url":"https://api.github.com/users/Organiceme","html_url":"https://github.com/Organiceme","followers_url":"https://api.github.com/users/Organiceme/followers","following_url":"https://api.github.com/users/Organiceme/following{/other_user}","gists_url":"https://api.github.com/users/Organiceme/gists{/gist_id}","starred_url":"https://api.github.com/users/Organiceme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Organiceme/subscriptions","organizations_url":"https://api.github.com/users/Organiceme/orgs","repos_url":"https://api.github.com/users/Organiceme/repos","events_url":"https://api.github.com/users/Organiceme/events{/privacy}","received_events_url":"https://api.github.com/users/Organiceme/received_events","type":"Organization","site_admin":false},"repo":{"id":38761172,"name":"docker-launchpad","full_name":"Organiceme/docker-launchpad","owner":{"login":"Organiceme","id":4245628,"avatar_url":"https://avatars.githubusercontent.com/u/4245628?v=3","gravatar_id":"","url":"https://api.github.com/users/Organiceme","html_url":"https://github.com/Organiceme","followers_url":"https://api.github.com/users/Organiceme/followers","following_url":"https://api.github.com/users/Organiceme/following{/other_user}","gists_url":"https://api.github.com/users/Organiceme/gists{/gist_id}","starred_url":"https://api.github.com/users/Organiceme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Organiceme/subscriptions","organizations_url":"https://api.github.com/users/Organiceme/orgs","repos_url":"https://api.github.com/users/Organiceme/repos","events_url":"https://api.github.com/users/Organiceme/events{/privacy}","received_events_url":"https://api.github.com/users/Organiceme/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Organiceme/docker-launchpad","description":"Launchpad container for continuous deployment","fork":false,"url":"https://api.github.com/repos/Organiceme/docker-launchpad","forks_url":"https://api.github.com/repos/Organiceme/docker-launchpad/forks","keys_url":"https://api.github.com/repos/Organiceme/docker-launchpad/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Organiceme/docker-launchpad/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Organiceme/docker-launchpad/teams","hooks_url":"https://api.github.com/repos/Organiceme/docker-launchpad/hooks","issue_events_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/events{/number}","events_url":"https://api.github.com/repos/Organiceme/docker-launchpad/events","assignees_url":"https://api.github.com/repos/Organiceme/docker-launchpad/assignees{/user}","branches_url":"https://api.github.com/repos/Organiceme/docker-launchpad/branches{/branch}","tags_url":"https://api.github.com/repos/Organiceme/docker-launchpad/tags","blobs_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/refs{/sha}","trees_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Organiceme/docker-launchpad/statuses/{sha}","languages_url":"https://api.github.com/repos/Organiceme/docker-launchpad/languages","stargazers_url":"https://api.github.com/repos/Organiceme/docker-launchpad/stargazers","contributors_url":"https://api.github.com/repos/Organiceme/docker-launchpad/contributors","subscribers_url":"https://api.github.com/repos/Organiceme/docker-launchpad/subscribers","subscription_url":"https://api.github.com/repos/Organiceme/docker-launchpad/subscription","commits_url":"https://api.github.com/repos/Organiceme/docker-launchpad/commits{/sha}","git_commits_url":"https://api.github.com/repos/Organiceme/docker-launchpad/git/commits{/sha}","comments_url":"https://api.github.com/repos/Organiceme/docker-launchpad/comments{/number}","issue_comment_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/comments{/number}","contents_url":"https://api.github.com/repos/Organiceme/docker-launchpad/contents/{+path}","compare_url":"https://api.github.com/repos/Organiceme/docker-launchpad/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Organiceme/docker-launchpad/merges","archive_url":"https://api.github.com/repos/Organiceme/docker-launchpad/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Organiceme/docker-launchpad/downloads","issues_url":"https://api.github.com/repos/Organiceme/docker-launchpad/issues{/number}","pulls_url":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls{/number}","milestones_url":"https://api.github.com/repos/Organiceme/docker-launchpad/milestones{/number}","notifications_url":"https://api.github.com/repos/Organiceme/docker-launchpad/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Organiceme/docker-launchpad/labels{/name}","releases_url":"https://api.github.com/repos/Organiceme/docker-launchpad/releases{/id}","created_at":"2015-07-08T15:00:21Z","updated_at":"2015-07-14T07:50:25Z","pushed_at":"2015-07-13T14:56:19Z","git_url":"git://github.com/Organiceme/docker-launchpad.git","ssh_url":"git@github.com:Organiceme/docker-launchpad.git","clone_url":"https://github.com/Organiceme/docker-launchpad.git","svn_url":"https://github.com/Organiceme/docker-launchpad","homepage":"","size":152,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1"},"html":{"href":"https://github.com/Organiceme/docker-launchpad/pull/1"},"issue":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/1"},"comments":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/Organiceme/docker-launchpad/statuses/27116d8ea84239f8c2c63992b12c699c16503d3d"}}}}