From 1fdd87ac96bcd764a08f180e88d1a45ba1d9985c Mon Sep 17 00:00:00 2001 From: Daniel Welch Date: Mon, 25 Feb 2019 19:13:03 -0600 Subject: [PATCH 1/3] added endpoint for docker pull --- index.js | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/index.js b/index.js index 0a1745d..7df4aa2 100644 --- a/index.js +++ b/index.js @@ -429,6 +429,42 @@ app.post('/container/:containerId/exec', function(req, res) { }); }) + +/** + * Pull the lastest image for the given repository, with or without tag + */ +app.get('/pull/:repoTag', function (req, res) { + var repoTag = req.params.repoTag; + console.log("Pull" + repoTag); + docker.pull(repoTag, function (err, stream) { + if (err) { + if (config.get("debug")) { + console.log("Failed to pull docker image " + repoTag); + console.log(err); + } + + res.status(500); + res.send(err); + return; + } + console.log("Pulling image..."); + const chunks = []; + stream.on("data", function (chunk) { + chunks.push(chunk.toString()); + }); + + // Send the buffer or you can put it into a var + stream.on("end", function () { + // We remove the first 8 chars as the contain a unicode START OF HEADING followed by ENQUIRY. + res.send({ + status: true, + jresult: chunks.join('').substr(8) + }); + }); + }); +}); + + //Attempt to connect to the Docker daemon switch (config.get("docker_connection:type")) { case "http": From e90a851c0afb5604dd88ef869c595470d71fc40f Mon Sep 17 00:00:00 2001 From: Daniel Welch Date: Tue, 26 Feb 2019 19:08:35 -0600 Subject: [PATCH 2/3] fix url arg parse to allow for '/' in arg --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 7df4aa2..1146e14 100644 --- a/index.js +++ b/index.js @@ -433,8 +433,8 @@ app.post('/container/:containerId/exec', function(req, res) { /** * Pull the lastest image for the given repository, with or without tag */ -app.get('/pull/:repoTag', function (req, res) { - var repoTag = req.params.repoTag; +app.get('/pull/*', function (req, res) { + var repoTag = req.params[0]; console.log("Pull" + repoTag); docker.pull(repoTag, function (err, stream) { if (err) { From 1df20e287db3348bbf76e94eb2c9425edebc6b10 Mon Sep 17 00:00:00 2001 From: Daniel Welch Date: Tue, 26 Feb 2019 23:10:51 -0600 Subject: [PATCH 3/3] add additional docker pull endpoint implementing webhook callback --- index.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/index.js b/index.js index 1146e14..850e984 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ var bodyParser = require('body-parser'); var Docker = require('dockerode'); var yaml = require("node-yaml"); var fs = require('fs'); +var http = require('http'); var Config = require('merge-config'); var config = new Config(); var docker = false; @@ -465,6 +466,51 @@ app.get('/pull/*', function (req, res) { }); +/** + * Pull the latest image for the given repository/tag. + * When the pull is complete, notify the provided callback_uri of success or failure. + */ +app.post('/pull/*', function (req, res) { + var repoTag = req.params[0]; + console.log("Pull" + repoTag + "asynchronously"); + var callback = req.body.callback_uri ? req.body.callback_uri : false; + if (callback == "" || !callback) { + res.send({ + status: false, + error: "No callback_uri specified. Use GET /pull/* to pull without a callback." + }); + res.status(400); + return; + } else { + res.send({ + status: true, + result: "Started pulling " + repoTag + }) + } + docker.pull(repoTag, function (err, stream) { + if (err) { + if (config.get("debug")) { + console.log("Failed to pull docker image " + repoTag); + console.log(err); + } + var data = { status: false, error: `Failed to pull docker image ${repoTag}` }; + postCallbackRequest(callback, data); + return; + } + console.log("Pulling image " + repoTag); + const chunks = []; + stream.on("data", function (chunk) { + chunks.push(chunk.toString()); + }); + + stream.on("end", function () { + var data = { status: true, result: `Finished pulling docker image ${repoTag}` } + postCallbackRequest(callback, data) + }); + }); +}); + + //Attempt to connect to the Docker daemon switch (config.get("docker_connection:type")) { case "http": @@ -567,3 +613,16 @@ function getContainer(name, cb, error) }); }); } + +function postCallbackRequest(url, data) +{ + var reqOpts = { method: 'POST', headers: { 'content-type': 'application/json' } }; + var req = http.request(url, reqOpts, function (res) { + res.on('end', function () { console.log(`Message sent to callback uri: ${data}`) }); + }); + req.on('error', function (err) { + console.error(`Error sending POST request to callback URI: ${err.message}`); + }); + req.write(JSON.stringify(data)); + req.end(); +}