Init: Create & Init dayu Project...
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		
							
								
								
									
										4
									
								
								packages/core/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/core/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/core/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/core/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										11
									
								
								packages/core/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								packages/core/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
# `@dayu/core`
 | 
			
		||||
 | 
			
		||||
> TODO: description
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
const core = require('@dayu/core');
 | 
			
		||||
 | 
			
		||||
// TODO: DEMONSTRATE API
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										33
									
								
								packages/core/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/core/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@dayu/core",
 | 
			
		||||
    "version": "0.0.1",
 | 
			
		||||
    "description": "> TODO: description",
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/dayu",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm-hosted/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "dev": "npx ts-node-dev --respawn --prefer-ts --debounce=1500 --ignore-watch=[] --project tsconfig.json",
 | 
			
		||||
        "debug": "npx nodemon -V --watch ../../node_modules --delay 1500ms dist/index.js",
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@cc-server/core": "^0.6.1",
 | 
			
		||||
        "@cc-server/ws": "^0.6.1",
 | 
			
		||||
        "@dayu/docker-api": "^0.0.1",
 | 
			
		||||
        "axios": "^0.19.0"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@types/express": "^4.17.0",
 | 
			
		||||
        "@types/socket.io": "^2.1.2",
 | 
			
		||||
        "rimraf": "^2.6.3",
 | 
			
		||||
        "ts-node-dev": "^1.0.0-pre.40",
 | 
			
		||||
        "typescript": "^3.5.2"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								packages/core/public/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								packages/core/public/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
	<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2.2.0/dist/socket.io.js"> </script>
 | 
			
		||||
	<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@3.12.2/dist/xterm.css" />
 | 
			
		||||
	<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@3.12.2/dist/addons/fullscreen/fullscreen.css">
 | 
			
		||||
 | 
			
		||||
	<script src="https://cdn.jsdelivr.net/npm/xterm@3.12.2/dist/xterm.js"></script>
 | 
			
		||||
	<script src="https://cdn.jsdelivr.net/npm/xterm@3.12.2/dist/addons/fit/fit.js"></script>
 | 
			
		||||
	<script src="https://cdn.jsdelivr.net/npm/xterm@3.12.2/dist/addons/attach/attach.js"></script>
 | 
			
		||||
	<script src="https://cdn.jsdelivr.net/npm/xterm@3.12.2/dist/addons/fullscreen/fullscreen.js"></script>
 | 
			
		||||
	<style>
 | 
			
		||||
		#terminal-container .terminal.xterm {
 | 
			
		||||
			height: 100%;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		#terminal-container .xterm-viewport {
 | 
			
		||||
			height: 100% !important;
 | 
			
		||||
		}
 | 
			
		||||
	</style>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
	<div id="terminal" style="height: 100%;"></div>
 | 
			
		||||
	<script type="text/javascript" src="js/index.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										68
									
								
								packages/core/public/js/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								packages/core/public/js/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
let command = '';
 | 
			
		||||
Terminal.applyAddon(fit);
 | 
			
		||||
Terminal.applyAddon(attach);
 | 
			
		||||
Terminal.applyAddon(fullscreen);
 | 
			
		||||
var term = new Terminal({
 | 
			
		||||
    experimentalCharAtlas: 'dynamic',
 | 
			
		||||
    cursorBlink: false,
 | 
			
		||||
});
 | 
			
		||||
term.open(document.getElementById('terminal'));
 | 
			
		||||
term.toggleFullScreen();
 | 
			
		||||
term.fit();
 | 
			
		||||
 | 
			
		||||
window.onresize = function() {
 | 
			
		||||
    term.fit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let query = {}
 | 
			
		||||
location.search.substring(1).split("&").forEach(q => {
 | 
			
		||||
    let qy = q.split("=", 2);
 | 
			
		||||
    query[qy[0]] = qy[1]
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
console.log(query);
 | 
			
		||||
 | 
			
		||||
var socket = io('/container', {
 | 
			
		||||
    path: '/ws',
 | 
			
		||||
    transports: ['websocket']
 | 
			
		||||
});
 | 
			
		||||
socket.on('connect', () => {
 | 
			
		||||
    term.writeln('connect')
 | 
			
		||||
    if (query.action) {
 | 
			
		||||
        term.writeln(`Recover Action: ${query.action} Data: ${query.data}`)
 | 
			
		||||
        switch (query.action) {
 | 
			
		||||
            case "container":
 | 
			
		||||
                socket.emit('logs', {
 | 
			
		||||
                    id: query.data,
 | 
			
		||||
                    since: Date.now() / 1000 - 60 * 15,
 | 
			
		||||
                    until: Date.now() / 1000,
 | 
			
		||||
                    stderr: false,
 | 
			
		||||
                    tail: "all"
 | 
			
		||||
                })
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
term.on('data', async data => {
 | 
			
		||||
    if (data == '\t') {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    term.write(data);
 | 
			
		||||
    if (data == '\r') {
 | 
			
		||||
        term.write('\n');
 | 
			
		||||
        socket.emit('logs', {
 | 
			
		||||
            id: command
 | 
			
		||||
        })
 | 
			
		||||
        command = '';
 | 
			
		||||
    } else {
 | 
			
		||||
        command += data;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
socket.on('message', data => {
 | 
			
		||||
    term.write(data.toString() + '\r\n');
 | 
			
		||||
});
 | 
			
		||||
socket.on('disconnect', () => {
 | 
			
		||||
    term.reset();
 | 
			
		||||
    term.writeln('disconnect');
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										36
									
								
								packages/core/src/controller/container.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								packages/core/src/controller/container.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
import * as docker from '@dayu/docker-api'
 | 
			
		||||
import { io, interfaces, namespace, listener, Message } from '@cc-server/ws'
 | 
			
		||||
import { controller, httpGet, requestParam } from '@cc-server/binding'
 | 
			
		||||
 | 
			
		||||
@controller('/container')
 | 
			
		||||
class ContainerController {
 | 
			
		||||
    @httpGet('/list')
 | 
			
		||||
    public async list() {
 | 
			
		||||
        return await docker.container.list({
 | 
			
		||||
            filters: JSON.stringify({
 | 
			
		||||
 | 
			
		||||
            })
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    @httpGet('/:id')
 | 
			
		||||
    public async info(@requestParam('id') id: string) {
 | 
			
		||||
        return await docker.container;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@namespace("/container")
 | 
			
		||||
class ContainerNamespace extends interfaces.Namespace {
 | 
			
		||||
    @listener()
 | 
			
		||||
    async logs(socket: io.Socket, data: any) {
 | 
			
		||||
        try {
 | 
			
		||||
            let stream = await docker.container.logs(data.id, data);
 | 
			
		||||
            this.defer(socket, () => stream.connection.destroy());
 | 
			
		||||
            stream.on('data', (chunk: ArrayBuffer) => {
 | 
			
		||||
                let log = Buffer.from(chunk.slice(8, chunk.byteLength - 1)).toString();
 | 
			
		||||
                socket.send(log);
 | 
			
		||||
            })
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            return new Message(ex.message);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								packages/core/src/controller/node.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								packages/core/src/controller/node.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
import { controller, httpGet, httpPost } from 'inversify-express-utils';
 | 
			
		||||
import * as docker from '@dayu/docker-api'
 | 
			
		||||
 | 
			
		||||
@controller('/node')
 | 
			
		||||
class NodeController {
 | 
			
		||||
    @httpGet('/list')
 | 
			
		||||
    public async list() {
 | 
			
		||||
        return await docker.node.list();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								packages/core/src/controller/stack.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								packages/core/src/controller/stack.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
import { controller, httpGet, httpPost, requestParam } from 'inversify-express-utils';
 | 
			
		||||
import * as docker from '@dayu/docker-api'
 | 
			
		||||
 | 
			
		||||
const STACK_LABEL = 'com.docker.stack.namespace';
 | 
			
		||||
 | 
			
		||||
@controller('/stack')
 | 
			
		||||
class StackController {
 | 
			
		||||
    @httpGet('/list')
 | 
			
		||||
    public async list() {
 | 
			
		||||
        let stacks: { [key: string]: string[] } = {};
 | 
			
		||||
        let services = await docker.service.list();
 | 
			
		||||
        for (const service of services) {
 | 
			
		||||
            let stackName = service.Spec.Labels[STACK_LABEL]
 | 
			
		||||
            if (stackName) {
 | 
			
		||||
                let stack = stacks[stackName] || [];
 | 
			
		||||
                stack.push(service.Spec.Name);
 | 
			
		||||
                stacks[stackName] = stack;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return stacks;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @httpGet('/:stack')
 | 
			
		||||
    public async details(@requestParam('stack') stack: string) {
 | 
			
		||||
        let filter: any = {}
 | 
			
		||||
        filter[`${STACK_LABEL}=${stack}`] = true
 | 
			
		||||
        let filterOpt = {
 | 
			
		||||
            filters: JSON.stringify({
 | 
			
		||||
                "label": filter
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
        let services = await docker.service.list(filterOpt)
 | 
			
		||||
        let networks = await docker.network.list(filterOpt)
 | 
			
		||||
        let containers = await docker.container.list(filterOpt);
 | 
			
		||||
        return {
 | 
			
		||||
            services: services.map(service => service.Spec.Name),
 | 
			
		||||
            networks: networks.map(network => network.Name),
 | 
			
		||||
            containers: containers.map(container => container.Names[0].substring(1))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								packages/core/src/controller/swarm.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								packages/core/src/controller/swarm.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import { controller, httpGet, httpPost } from 'inversify-express-utils';
 | 
			
		||||
import * as docker from '@dayu/docker-api'
 | 
			
		||||
 | 
			
		||||
@controller('/swarm')
 | 
			
		||||
class SwarmController {
 | 
			
		||||
    @httpGet('/info')
 | 
			
		||||
    public async version() {
 | 
			
		||||
        return await docker.swarm.inspect();
 | 
			
		||||
    }
 | 
			
		||||
    @httpPost('/init')
 | 
			
		||||
    public async info() {
 | 
			
		||||
        let info = await docker.swarm.init({
 | 
			
		||||
            ListenAddr: "0.0.0.0:2377",
 | 
			
		||||
            AdvertiseAddr: "192.168.0.3:2377",
 | 
			
		||||
            // DefaultAddrPool: [
 | 
			
		||||
            //     "10.10.0.0/8",
 | 
			
		||||
            //     "20.20.0.0/8"
 | 
			
		||||
            // ],
 | 
			
		||||
            // ForceNewCluster: false,
 | 
			
		||||
            // SubnetSize: 24
 | 
			
		||||
        })
 | 
			
		||||
        return info;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/core/src/controller/system.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/core/src/controller/system.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import { controller, httpGet, httpPost } from 'inversify-express-utils';
 | 
			
		||||
import * as docker from '@dayu/docker-api'
 | 
			
		||||
 | 
			
		||||
@controller('')
 | 
			
		||||
class SystemController {
 | 
			
		||||
    @httpGet('/version')
 | 
			
		||||
    public async version() {
 | 
			
		||||
        return await docker.system.version()
 | 
			
		||||
    }
 | 
			
		||||
    @httpGet('/info')
 | 
			
		||||
    public async info() {
 | 
			
		||||
        let info = await docker.system.info()
 | 
			
		||||
        return info;
 | 
			
		||||
    }
 | 
			
		||||
    @httpGet('/events')
 | 
			
		||||
    public async event() {
 | 
			
		||||
        await docker.system.events((event) => {
 | 
			
		||||
            if (!event) { return }
 | 
			
		||||
            console.log(event)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								packages/core/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								packages/core/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import { CcServerBoot } from '@cc-server/core'
 | 
			
		||||
import * as fs from 'fs'
 | 
			
		||||
import * as path from 'path'
 | 
			
		||||
 | 
			
		||||
//process.env.DOCKER_HOST = 'https://ndcli.yumc.pw'
 | 
			
		||||
process.env.DOCKER_HOST = '/var/run/docker.sock'
 | 
			
		||||
 | 
			
		||||
let server = new CcServerBoot();
 | 
			
		||||
 | 
			
		||||
let modulesDir = path.join(__dirname, 'controller')
 | 
			
		||||
let list = fs.readdirSync(modulesDir);
 | 
			
		||||
 | 
			
		||||
for (let file of list) {
 | 
			
		||||
    let moduleDir = path.join(modulesDir, file)
 | 
			
		||||
    let stat = fs.statSync(moduleDir);
 | 
			
		||||
    if (stat.isFile() && file.endsWith('.js')) {
 | 
			
		||||
        require(moduleDir);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
server.static().build().start();
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/core/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/core/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user