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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
node_modules
node_modules/
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
191 changes: 145 additions & 46 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var debug = require('debug')('docker-run')

var noop = function() {}

var run = function(image, opts) {
var run = function(image,opts) {
if (!opts) opts = {}

var request = docker(opts.host, {version:'v1.14'})
Expand All @@ -27,7 +27,10 @@ var run = function(image, opts) {
AttachStderr: !opts.fork,
OpenStdin: !opts.fork,
StdinOnce: !opts.fork,
Cmd: opts.argv || [],
Memory:20*1024*1024,
MemorySwap:40*1024*1024,
CpuShares:512,
Cmd: opts.argv || ["bash"],
Tty: tty,
Image: image,
ExposedPorts: {},
Expand Down Expand Up @@ -57,7 +60,7 @@ var run = function(image, opts) {
Object.keys(opts.volumes).forEach(function(host) {
var container = opts.volumes[host]
copts.Volumes[host] = {}
sopts.Binds.push(host+':'+container+':rw')
sopts.Binds.push(host+':'+container+':r')
})
}

Expand All @@ -83,18 +86,79 @@ var run = function(image, opts) {
resize(that.id, wid, hei, noop)
})
}

var create = function(cb) {
debug('creating container')
var qs = {}
if (opts.name) qs.name = opts.name
request.post('/containers/create', {json: copts, qs:qs}, cb)
console.log('creating container')
request.post('/containers/create', {json: copts}, cb)
}

var pull = function(cb){
console.log('pull image')
that.emit('pbegin')
if (opts.fork) return cb()

debug('pulling to stdio for %s', image)
var stdin = request.post('/images/create', {
timeout: 20000,
qs:{
fromImage:image,
repo:"docker2.peilong.me:5000"
},
headers: {
'Content-Length': '0',
'Content-Type': 'application/json'
}
}, function(err, response) {
var iserror = false
if(err){
console.log(err);
that.emit('error',err);
}else{

response.on('data', function(data){
var resobj = JSON.parse(data.toString())
if(resobj.hasOwnProperty('error')){
iserror = true

that.stdout.write(resobj.error+'\n');
that.emit('error',resobj);
}else{
that.stdout.write(resobj.status+'\n');
}

})
response.on('error',function(err){
console.log(err);
that.emit('error',err);
})
response.on('end',function(){
if(iserror == false){
console.log('response end')
that.emit('pend')
that.emit('exit', 1024)
that.emit('close')
}
})
//
//if(tty){
// cb(null,stdin,response)
//}
//
//
//var parser = response.pipe(raw())
//cb(null, stdin, parser.stdout, parser.stderr)

}

})

if (!stdin._header && stdin._implicitHeader) stdin._implicitHeader()
if (stdin._send) stdin._send(new Buffer(0))
}

var attach = function(id, cb) {
if (opts.fork) return cb()

debug('attaching to stdio for %s', id)
console.log('attaching to stdio for %s', id)
var stdin = request.post('/containers/'+id+'/attach', {
qs: {
stderr: 1,
Expand Down Expand Up @@ -123,12 +187,12 @@ var run = function(image, opts) {

var remove = function(id, cb) {
if (opts.remove === false) return cb()
debug('removing %s', id)
console.log('removing %s', id)
request.del('/containers/'+id, cb)
}

var stop = function(id, cb) {
debug('stopping %s', id)
console.log('stopping %s', id)
request.post('/containers/'+id+'/stop', {
qs: opts.wait || 10,
json: true,
Expand All @@ -137,7 +201,7 @@ var run = function(image, opts) {
}

var start = function(id, cb) {
debug('starting %s', id)
console.log('starting %s', id)
request.post('/containers/'+id+'/start', {json: sopts}, cb)
}

Expand All @@ -152,6 +216,10 @@ var run = function(image, opts) {
})
}

var inspect = function(id,cb){
console.log('inspect %s', id)
request.get('/containers/'+id+'/json', {json: true}, cb)
}
var resize = function(id, wid, hei, cb) {
debug('resizing %s to %dx%d', id, wid, hei)
request.post('/containers/'+id+'/resize', {
Expand All @@ -173,44 +241,75 @@ var run = function(image, opts) {
debug('%s crashed with error %s', id, err.message)
that.emit('error', err)
}

create(function(err, container) {
if (err) return onerror(null, err)

debug('spawned %s', container.Id)
that.id = container.Id

attach(container.Id, function(err, stdin, stdout, stderr) {
if (err) return onerror(container.Id, err)

start(container.Id, function(err) {
if (err) return onerror(container.Id, err)

resizeDefault(container.Id, function(err) {
if (err) return onerror(container.Id, err)

if (!stdin) return that.emit('spawn', that.id)

pump(that.stdin, stdin)
pump(stdout, that.stdout)
if (stderr) pump(stderr, that.stderr)
else that.stderr.end()

wait(container.Id, function(err, code) {
if (err) return onerror(container.Id, err)
remove(container.Id, function() {
that.emit('exit', code)
that.emit('close')
if (err){
if(err.status == 404){
//no such image,so we pull it
pull(function(err, stdin, stdout, stderr) {
if (err){
console.log(err)
return onerror(null, err)
}
if(tty){
if (!stdin) return that.emit('spawn', that.id)

pump(that.stdin, stdin)
pump(stdout, that.stdout)
if (stderr) pump(stderr, that.stderr)
else that.stderr.end()
}else{
}
})
})

that.emit('spawn', that.id)
})
})
})
}else{
return onerror(null, err)
}

}else{
debug('spawned %s', container.Id)
that.id = container.Id

if(tty){
attach(container.Id, function(err, stdin, stdout, stderr) {
if (err) return onerror(container.Id, err)

start(container.Id, function(err) {
if (err) return onerror(container.Id, err)

resizeDefault(container.Id, function(err) {
if (err) return onerror(container.Id, err)

if (!stdin) return that.emit('spawn', that.id)

pump(that.stdin, stdin)
pump(stdout, that.stdout)
if (stderr) pump(stderr, that.stderr)
else that.stderr.end()

wait(container.Id, function(err, code) {
if (err) return onerror(container.Id, err)
remove(container.Id, function() {
that.emit('exit', code)
that.emit('close')
})
})

that.emit('spawn', that.id)
})
})
})
}else{
start(container.Id, function(err) {
if (err) return onerror(container.Id, err)
inspect(container.Id,function(err,json){
if (err) return onerror(container.Id, err)
that.emit('json',json)
})
})
}
}
})

return that
}

module.exports = run
module.exports = run
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@
"docker",
"run"
],
"author": "Mathias Buus",
"author": {
"name": "Mathias Buus"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/mafintosh/docker-run/issues"
},
"homepage": "https://github.com/mafintosh/docker-run"
"homepage": "https://github.com/mafintosh/docker-run",
"readme": "# docker-run\n\nStart a docker image and attach to it\n\n```\nnpm install docker-run\n```\n\n[There is also a command line tool available](https://github.com/mafintosh/docker-run#command-line-usage)\n\n## Usage\n\n``` js\nvar run = require('docker-run')\n\nvar child = run('mafintosh/dev', {tty:true})\n\nprocess.stdin.setRawMode(true)\nprocess.stdin.pipe(child.stdin)\nchild.stdout.pipe(process.stdout)\nchild.stderr.pipe(process.stderr)\n```\n\n## API\n\n* `child = run(image, [options])`\n\nWhere options can be\n\n``` js\n{\n net: 'bridge', // network mode (auto | host | bridge). defaults to bridge\n tty: true, // be a tty. defaults to false\n fork: true, // fork (do not attach stdio). defaults to false\n remove: true, // remove the container on stop. defaults to true\n dns: ['8.8.8.8'], // set custom dns servers\n ports: {\n 8080: 8081 // expose container 8080 to host 8081\n },\n volumes: {\n '/root': '/tmp' // expose container /root to host /tmp\n },\n env: {\n FOO: 'bar' // set env vars\n },\n entrypoint: '/bin/bash' // override entrypoint on container\n}\n```\n\n* `child.stdin`, `child.stderr`, `child.stdout`\n\nThe stdio streams for the container. Is `null` if `fork: true`\n\n* `child.destroy()`\n\nDestroy the child container\n\n* `child.resize(wid, hei)`\n\nResize the container pty (if `tty: true`)\n\n## Events\n\n* `child.on('exit', exitCode)`\n\nEmitted when the container exits\n\n* `child.on('spawn', containerId)`\n\nEmitted when the container is spawned\n\n* `child.on('error', error)`\n\nEmitted if the container experiences a fatal error\n\n## Command line usage\n\nTo install the command line tool do\n\n```\nnpm install -g docker-run\n```\n\nAnd then run\n\n```\ndocker-run --help\n```\n\nTo view the help. In general to run an image do\n\n```\ndocker-run [image]\n```\n\n## License\n\nMIT",
"readmeFilename": "README.md"
}