Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@
FROM node:16-alpine
USER root

RUN apk add curl gnupg

RUN wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.7.tgz \
&& tar -xvzf docker-20.10.7.tgz \
&& cp docker/* /usr/bin/
RUN apk add curl gnupg jq util-linux-misc

RUN mkdir -p /home/probo/app
COPY . /home/probo/app
Expand All @@ -30,6 +26,10 @@ RUN cd /home/probo/app/ && npm install

WORKDIR /home/probo/app

RUN cd /home/probo/app && mkdir arm && mkdir x64 && \
cd arm && wget https://download.docker.com/linux/static/stable/aarch64/docker-20.10.9.tgz && cd .. && \
cd x64 && wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.9.tgz && cd ..

EXPOSE 3010 3020

CMD ["sh", "/home/probo/app/bin/startup.sh"]
11 changes: 11 additions & 0 deletions bin/startup.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
#!/bin/sh

architecture=$(lscpu -J | jq -r '.lscpu[0].data')
if [ "$architecture" = "x86_64" ]; then
cd /home/probo/app/x64
else
cd /home/probo/app/arm
fi

tar -xzf docker-20.10.9.tgz
cp docker/* /usr/bin/
docker --version

if [[ "$CONTAINER_MANAGER" = 1 ]]; then
exec /home/probo/app/bin/probo container-manager -c /etc/probo/container-manager.yaml
fi
Expand Down
10 changes: 1 addition & 9 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,9 @@ if [ -z "$1" ]; then
fi

printf "${Cyan}Building Probo..............................."
stuff=`docker build . -q -t $1/container-manager:$tag`;
stuff=`docker buildx build --quiet --platform linux/amd64,linux/arm64 -t $1/probo:$tag --push .`;
if [[ $? == 0 ]]; then
printf "${Green}[ok]\n";
printf "${Cyan}Pushing to Docker Repository................."
stuff=`docker push -q $1/container-manager:$tag`
if [[ $? == 0 ]]; then
printf "${Green}[ok]\n";
else
printf "${Red}[error]\n";
exit 1;
fi
else
printf "${Red}[error]\n";
exit 1;
Expand Down
100 changes: 51 additions & 49 deletions lib/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ const SRC_DIR = '/src';
* @param {string} options.assets.url - Assets server URL.
* @param {string} [options.assets.token] - API token for assets server.
*/
var Container = function (options) {
var Container = function(options) {
this.create = this.create.bind(this);
this.docker = new Docker(options.docker);
this.build = options.build;
this.jobConfig = options.jobConfig;
this.log = options.log
? options.log.child({ component: 'container' })
: bunyan.createLogger({ name: 'container' });
? options.log.child({component: 'container'})
: bunyan.createLogger({name: 'container'});
this.containerName = options.containerName || null;
this.containerId = options.containerId || null;
this.container = this.containerId
Expand All @@ -49,7 +49,7 @@ var Container = function (options) {

// wrap emit method to also emit a generic event
var _emit = this.emit;
this.emit = function (event) {
this.emit = function(event) {
var args = Array.prototype.slice.call(arguments);

// emit original event
Expand All @@ -62,7 +62,7 @@ var Container = function (options) {
};
util.inherits(Container, EventEmitter);

Container.prototype.buildSetupTasks = Promise.promisify(function (done) {
Container.prototype.buildSetupTasks = Promise.promisify(function(done) {
var jobConfig = this.jobConfig;

var container = this;
Expand All @@ -87,7 +87,7 @@ Container.prototype.buildSetupTasks = Promise.promisify(function (done) {
done(null, tasks);
});

Container.prototype._createDownloader = function (build, project) {
Container.prototype._createDownloader = function(build, project) {
// map provider type to downloader class name
var downloaders = {
github: 'GithubDownloader',
Expand All @@ -106,9 +106,10 @@ Container.prototype._createDownloader = function (build, project) {
var Downloader;
try {
Downloader = require(`./plugins/TaskRunner/${plugin}`);
} catch (e) {
}
catch (e) {
var msg = `Download: failed to load supported downloader for provider ${providerType}: ${e.message}`;
this.log.error({ err: e, plugin }, msg);
this.log.error({err: e, plugin}, msg);
throw new Error(msg);
}

Expand All @@ -119,14 +120,14 @@ Container.prototype._createDownloader = function (build, project) {
});
};

Container.prototype.buildUserTasks = Promise.promisify(function (done) {
Container.prototype.buildUserTasks = Promise.promisify(function(done) {
var self = this;
var config = this.jobConfig;
var tasks = [];
var steps = config.steps || [];
steps = Array.isArray(steps) ? steps : [steps];

steps.forEach(function (step) {
steps.forEach(function(step) {
var plugin = step.plugin || 'Shell';

if (self.provisionerPlugins[plugin]) {
Expand All @@ -147,15 +148,15 @@ Container.prototype.buildUserTasks = Promise.promisify(function (done) {
*
* @return {booelean} - The status of the tasks.
*/
Container.prototype.runTasks = function () {
Container.prototype.runTasks = function() {
this.emit('running tasks');

var self = this;
return this.buildUserTasks().each(function (task) {
return task.run().then(function (result) {
return this.buildUserTasks().each(function(task) {
return task.run().then(function(result) {
// result: {stream, exec (Promise), task}
result.streams.combined.pipe(process.stdout);
return result.exec.then(function (exec) {
return result.exec.then(function(exec) {
console.log('Exit code:', exec.ExitCode);

self.emit('tasks complete', result);
Expand All @@ -165,14 +166,14 @@ Container.prototype.runTasks = function () {
});
};

Container.prototype.runBuild = Promise.promisify(function (done) {
Container.prototype.runBuild = Promise.promisify(function(done) {
var self = this;
self.create(function (error, containerData) {
self.create(function(error, containerData) {
if (error) return done(error);

return self
.runTasks()
.then(function (EvaluatedTasks) {
.then(function(EvaluatedTasks) {
return containerData;
})
.nodeify(done);
Expand All @@ -184,7 +185,7 @@ Container.prototype.runBuild = Promise.promisify(function (done) {
*
* The done callback will be called with errors (if one occured).
*/
Container.prototype.create = Promise.promisify(function (done) {
Container.prototype.create = Promise.promisify(function(done) {
this.emit('creating');
done = wrapCallbackWithEmitter(this, 'created', done);

Expand Down Expand Up @@ -220,20 +221,20 @@ Container.prototype.create = Promise.promisify(function (done) {
if (this.build.pullRequest) {
if (this.build.pullRequest.htmlUrl) {
createOptions.Env.push(
`PULL_REQUEST_LINK=${this.build.pullRequest.htmlUrl}`
`PULL_REQUEST_LINK=${this.build.pullRequest.htmlUrl}`,
);
}
if (this.build.pullRequest.name) {
createOptions.Env.push(
`PULL_REQUEST_NAME="${this.build.pullRequest.name}"`
`PULL_REQUEST_NAME="${this.build.pullRequest.name}"`,
);
}
}
self.log.info(
{ env: createOptions.Env },
`Creating container for build ${this.build.id}`
{env: createOptions.Env},
`Creating container for build ${this.build.id}`,
);
docker.createContainer(createOptions, function (error, container) {
docker.createContainer(createOptions, function(error, container) {
if (error) return done(error);
self.id = container.id;
self.container = container;
Expand All @@ -242,21 +243,21 @@ Container.prototype.create = Promise.promisify(function (done) {
self.log.info(`Starting container ${container.id}`);
if (self.attachLogs) {
container.attach(
{ stream: true, stdout: true, stderr: true },
function (error, stream) {
{stream: true, stdout: true, stderr: true},
function(error, stream) {
// TODO: We should consider collecting log output from the node and
// sending it to loom.
container.modem.demuxStream(
stream,
self.createLogWriteStream(),
self.createLogWriteStream()
self.createLogWriteStream(),
);
}
},
);
}
container.start(function (error, data) {
container.start(function(error, data) {
if (error) return done(error);
container.inspect(function (error, data) {
container.inspect(function(error, data) {
self.containerInfo = data;
done(error, data);
});
Expand All @@ -267,17 +268,17 @@ Container.prototype.create = Promise.promisify(function (done) {
/**
* Tries to create a container or finds one by the ID instead
*/
Container.prototype.findOrCreate = function () {};
Container.prototype.findOrCreate = function() {};

/**
* Returns the current status of the container
*
* @param {function} done - the callback function, if provided
* @return {function} - container inspect funnction, callback or promise
*/
Container.prototype.getState = function (done) {
Container.prototype.getState = function(done) {
return this.inspect()
.then(function (info) {
.then(function(info) {
return info.State;
})
.asCallback(done);
Expand All @@ -286,20 +287,20 @@ Container.prototype.getState = function (done) {
/**
* Returns result of .inspect on container
*/
Container.prototype.inspect = Promise.promisify(function (opts, done) {
Container.prototype.inspect = Promise.promisify(function(opts, done) {
if (typeof opts == 'function') {
done = opts;
opts = {};
}
this.container.inspect(opts, function (err, info) {
this.container.inspect(opts, function(err, info) {
return done(err, info);
});
});

/**
* Stop the container
*/
Container.prototype.stop = Promise.promisify(function (done) {
Container.prototype.stop = Promise.promisify(function(done) {
this.emit('stopping');
done = wrapCallbackWithEmitter(this, 'stopped', done);
this.container.stop(done);
Expand All @@ -308,7 +309,7 @@ Container.prototype.stop = Promise.promisify(function (done) {
/**
* restart (stop/start) container
*/
Container.prototype.restart = Promise.promisify(function (done) {
Container.prototype.restart = Promise.promisify(function(done) {
this.emit('restarting');
done = wrapCallbackWithEmitter(this, 'restarted', done);
this.container.restart(done);
Expand All @@ -317,7 +318,7 @@ Container.prototype.restart = Promise.promisify(function (done) {
/**
* start container
*/
Container.prototype.start = Promise.promisify(function (done) {
Container.prototype.start = Promise.promisify(function(done) {
this.emit('starting');
done = wrapCallbackWithEmitter(this, 'started', done);
this.container.start(done);
Expand All @@ -326,7 +327,7 @@ Container.prototype.start = Promise.promisify(function (done) {
/**
* DELETE container from the filesystem
*/
Container.prototype.remove = Promise.promisify(function (opts, done) {
Container.prototype.remove = Promise.promisify(function(opts, done) {
this.emit('removing');

if (typeof opts == 'function') {
Expand All @@ -345,12 +346,13 @@ Container.prototype.remove = Promise.promisify(function (opts, done) {
* @param {number} port - port number used on container
* @return {function} - function to get container info
*/
Container.prototype.getExposedPortFromContainerInfo = function (data, port) {
Container.prototype.getExposedPortFromContainerInfo = function(data, port) {
try {
return data.NetworkSettings.Ports[port + '/tcp'][0].HostPort;
} catch (e) {
}
catch (e) {
throw new Error(
'Could not find tcp port ' + port + ' on container ' + this.id
'Could not find tcp port ' + port + ' on container ' + this.id,
);
}
};
Expand All @@ -365,11 +367,11 @@ Container.prototype.getExposedPortFromContainerInfo = function (data, port) {
* arguments. The object has {virtualBytes, realBytes}, for the
* size of the inderlying image and container layer respectively.
*/
Container.prototype.getDiskUsage = Promise.promisify(function (done) {
var result = { realBytes: null, virtualBytes: null };
Container.prototype.getDiskUsage = Promise.promisify(function(done) {
var result = {realBytes: null, virtualBytes: null};

// stat the container to ensure that it's using the AUFS driver
this.container.inspect({ size: true }, function (err, info) {
this.container.inspect({size: true}, function(err, info) {
if (err) {
return done(null, result);
}
Expand All @@ -386,10 +388,10 @@ Container.prototype.getDiskUsage = Promise.promisify(function (done) {
* @param {string} image - The name of the image we are extracting build command info for.
* @return {object} - The command info on what is to be run.
*/
Container.prototype.buildCommandInfo = function (image) {
Container.prototype.buildCommandInfo = function(image) {
if (!image) {
throw new Error(
'Use an approved Probo Image in your .probo.yaml file. See https://docs.probo.ci/build/images/ for approved Probo Images.'
'Use an approved Probo Image in your .probo.yaml file. See https://docs.probo.ci/build/images/ for approved Probo Images.',
);
}

Expand All @@ -407,7 +409,7 @@ Container.prototype.buildCommandInfo = function (image) {
var protocol = service.protocol || 'tcp';
var portString = service.port + '/' + protocol;
exposedPorts[portString] = {};
portBindings[portString] = [{ HostPort: null }];
portBindings[portString] = [{HostPort: null}];
}
}
}
Expand All @@ -426,14 +428,14 @@ Container.prototype.provisionerPlugins = TaskRunnerPlugins;
* @param {object} options Options to pass to for the creation of the log stream.
* @return {stream} - The stream to write log files to.
*/
Container.prototype.createLogWriteStream = function (options) {
Container.prototype.createLogWriteStream = function(options) {
var stream = through2();
stream.pipe(process.stdout);
return stream;
};

function wrapCallbackWithEmitter(emitter, eventName, callback) {
return function () {
return function() {
var args = Array.prototype.slice.call(arguments);
args.unshift(eventName);
emitter.emit.apply(emitter, args);
Expand Down
Loading