diff --git a/.gitignore b/.gitignore index 3c3629e..c2658d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -node_modules +node_modules/ diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/index.js b/index.js index cd0381d..bc2bfd7 100644 --- a/index.js +++ b/index.js @@ -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'}) @@ -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: {}, @@ -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') }) } @@ -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, @@ -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, @@ -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) } @@ -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', { @@ -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 \ No newline at end of file +module.exports = run diff --git a/package.json b/package.json index 6aecce2..ba731ae 100644 --- a/package.json +++ b/package.json @@ -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" }