Init: Create & Init dayu Project...
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
commit
c47137ec4a
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
package-lock.json
|
||||
yarn.lock
|
38
http/dayu.http
Normal file
38
http/dayu.http
Normal file
@ -0,0 +1,38 @@
|
||||
@url=https://faas.n.yumc.pw
|
||||
|
||||
### System
|
||||
##### Info
|
||||
GET {{url}}/info
|
||||
|
||||
##### Version
|
||||
GET {{url}}/version
|
||||
|
||||
##### Events
|
||||
GET {{url}}/events
|
||||
|
||||
### Swarm
|
||||
@swarm={{url}}/swarm
|
||||
|
||||
##### Swarm Info
|
||||
GET {{swarm}}/info
|
||||
|
||||
### Swarm Init
|
||||
POST {{swarm}}/init
|
||||
|
||||
{}
|
||||
|
||||
### Stack
|
||||
@stack={{url}}/stack
|
||||
##### Stack List
|
||||
GET {{stack}}/list
|
||||
|
||||
##### Stack Remove
|
||||
POST {{stack}}/develop/remove
|
||||
|
||||
|
||||
### Container
|
||||
@container={{url}}/container
|
||||
|
||||
##### Container logs
|
||||
@id=6365041d2e52c5896dd14a5450920e482dddc33e6addaa07fab413bcda78d723
|
||||
GET {{container}}/{{id}}/logs
|
36
http/docker.http
Normal file
36
http/docker.http
Normal file
@ -0,0 +1,36 @@
|
||||
@url=https://dcli.yumc.pw/v1.39
|
||||
|
||||
### Info
|
||||
GET {{url}}/info
|
||||
|
||||
### Version
|
||||
GET {{url}}/version
|
||||
|
||||
### Swarm
|
||||
GET {{url}}/swarm
|
||||
|
||||
### Swarm Init
|
||||
POST {{url}}/swarm/init
|
||||
|
||||
{}
|
||||
|
||||
### Node
|
||||
GET {{url}}/nodes
|
||||
|
||||
### Container
|
||||
@cid=87514be54f3b9a34ac8ea74097d2053d73c7c535f34d3446bcbe16d6f2ba0f0f
|
||||
@container={{url}}/containers
|
||||
##### List
|
||||
GET {{container}}/json?filters={"label":{"com.docker.stack.namespace%3Dmonitor":false}}
|
||||
##### In
|
||||
GET {{container}}/{{cid}}/json
|
||||
|
||||
### Services
|
||||
GET {{url}}/services?filters={"mode":["global"]}
|
||||
|
||||
### Create Services
|
||||
POST {{url}}/services/create
|
||||
|
||||
{
|
||||
|
||||
}
|
27
lerna.json
Normal file
27
lerna.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "0.3.3",
|
||||
"changelog": {
|
||||
"labels": {
|
||||
"tag: new feature": ":rocket: New Feature",
|
||||
"tag: breaking change": ":boom: Breaking Change",
|
||||
"tag: bug fix": ":bug: Bug Fix",
|
||||
"tag: enhancement": ":nail_care: Enhancement",
|
||||
"tag: documentation": ":memo: Documentation",
|
||||
"tag: internal": ":house: Internal"
|
||||
},
|
||||
"cacheDir": ".changelog"
|
||||
},
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"command": {
|
||||
"run": {
|
||||
"stream": true
|
||||
},
|
||||
"publish": {
|
||||
"registry": "https://repo.yumc.pw/repository/npm-hosted/"
|
||||
}
|
||||
}
|
||||
}
|
20
package.json
Normal file
20
package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "dayu",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"author": "MiaoWoo <admin@yumc.pw>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "npx lerna run clean",
|
||||
"watch": "npx lerna run watch --concurrency 10",
|
||||
"build": "npx lerna run build",
|
||||
"lp": "npx lerna publish"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"devDependencies": {
|
||||
"lerna": "^3.14.1"
|
||||
}
|
||||
}
|
4
packages/common/.gitignore
vendored
Normal file
4
packages/common/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/node_modules
|
||||
/dist
|
||||
/package-lock.json
|
||||
/yarn.lock
|
22
packages/common/.npmignore
Normal file
22
packages/common/.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/common/README.md
Normal file
11
packages/common/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# `@dayu/common`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
const core = require('@dayu/common');
|
||||
|
||||
// TODO: DEMONSTRATE API
|
||||
```
|
27
packages/common/package.json
Normal file
27
packages/common/package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@dayu/common",
|
||||
"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 src/index.ts",
|
||||
"clean": "rimraf dist",
|
||||
"watch": "npx tsc --watch",
|
||||
"build": "yarn clean && npx tsc",
|
||||
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.3",
|
||||
"ts-node-dev": "^1.0.0-pre.40",
|
||||
"typescript": "^3.5.2"
|
||||
}
|
||||
}
|
28
packages/common/public/index.html
Normal file
28
packages/common/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/common/public/js/index.js
Normal file
68
packages/common/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');
|
||||
});
|
68
packages/common/src/api.ts
Normal file
68
packages/common/src/api.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import * as http from 'http'
|
||||
import axios, { AxiosResponse, AxiosRequestConfig, Method, AxiosInstance } from 'axios'
|
||||
|
||||
class HttpClient {
|
||||
private api: AxiosInstance;
|
||||
constructor() {
|
||||
const instanceConfig: AxiosRequestConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 5000
|
||||
}
|
||||
if (process.env.DOCKER_HOST.startsWith("/")) {
|
||||
instanceConfig.socketPath = process.env.DOCKER_HOST
|
||||
} else {
|
||||
instanceConfig.baseURL = process.env.DOCKER_HOST
|
||||
}
|
||||
this.api = axios.create(instanceConfig)
|
||||
}
|
||||
async get<T = any>(path: string, data?: object): Promise<T> {
|
||||
return await this.handle<T>("GET", path, { params: data });
|
||||
}
|
||||
async post<T = any>(path: string, data?: object): Promise<T> {
|
||||
return await this.handle<T>("POST", path, { data });
|
||||
}
|
||||
async stream<T = http.ServerResponse>(path: string, data?: object): Promise<T> {
|
||||
return await this.handle<T>("GET", path, { params: data, responseType: "stream" });
|
||||
}
|
||||
async handle<T>(method: Method, path: string, reqConfig?: AxiosRequestConfig): Promise<T> {
|
||||
let config: AxiosRequestConfig = {
|
||||
method,
|
||||
url: path,
|
||||
};
|
||||
let startTime = Date.now();
|
||||
Object.assign(config, reqConfig)
|
||||
let response: AxiosResponse;
|
||||
try {
|
||||
response = await this.api.request(config);
|
||||
return response.data as T
|
||||
} catch (ex) {
|
||||
if (!ex.response) { throw ex; }
|
||||
response = ex.response;
|
||||
if (this.isStream(response)) {
|
||||
let stream = response.data;
|
||||
response.data = await new Promise<T>((resolve, reject) => {
|
||||
let cache = '';
|
||||
stream.on('data', (chunk: ArrayBuffer) => { cache += chunk.toString() })
|
||||
stream.on('end', () => { resolve(JSON.parse(cache) as T); })
|
||||
})
|
||||
}
|
||||
throw new Error(JSON.stringify(response.data));
|
||||
} finally {
|
||||
if (response) {
|
||||
console.log(`============== API Invoke ==============
|
||||
REQUEST METHOD : ${method}
|
||||
REQUEST PATH : ${axios.getUri(config)}
|
||||
REQUEST PARAMS : ${JSON.stringify(config.params || {})}
|
||||
REQUEST BODY : ${JSON.stringify(config.data || {})}
|
||||
RESPONSE BODY : ${this.isStream(response) ? '<Stream>' : JSON.stringify(response.data)}
|
||||
HANDLE TIME : ${Date.now() - startTime}ms
|
||||
========================================`);
|
||||
}
|
||||
}
|
||||
}
|
||||
isStream(response: AxiosResponse) {
|
||||
return toString.call(response.data.pipe) === "[object Function]";
|
||||
}
|
||||
}
|
1
packages/common/src/index.ts
Normal file
1
packages/common/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './api'
|
7
packages/common/tsconfig.json
Normal file
7
packages/common/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"outDir": "dist"
|
||||
}
|
||||
}
|
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"
|
||||
}
|
||||
}
|
4
packages/docker-api/.gitignore
vendored
Normal file
4
packages/docker-api/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/node_modules
|
||||
/dist
|
||||
/package-lock.json
|
||||
/yarn.lock
|
22
packages/docker-api/.npmignore
Normal file
22
packages/docker-api/.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/docker-api/README.md
Normal file
11
packages/docker-api/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# `@dayu/core`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
const core = require('@dayu/core');
|
||||
|
||||
// TODO: DEMONSTRATE API
|
||||
```
|
29
packages/docker-api/package.json
Normal file
29
packages/docker-api/package.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "@dayu/docker-api",
|
||||
"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 src/index.ts",
|
||||
"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.3.3",
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.0.10",
|
||||
"ts-node-dev": "^1.0.0-pre.40",
|
||||
"typescript": "^3.5.2",
|
||||
"rimraf": "^2.6.3"
|
||||
}
|
||||
}
|
11
packages/docker-api/src/api/common.ts
Normal file
11
packages/docker-api/src/api/common.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export interface ObjectMap {
|
||||
[key: string]: {};
|
||||
}
|
||||
export interface StringMap {
|
||||
[key: string]: string;
|
||||
}
|
||||
export type PortSet = ObjectMap
|
||||
export type Options = StringMap
|
||||
export type Config = StringMap
|
||||
export type Labels = StringMap
|
||||
export type Ports = StringMap | ObjectMap
|
10
packages/docker-api/src/api/opts/common.ts
Normal file
10
packages/docker-api/src/api/opts/common.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export declare namespace query {
|
||||
export interface FilterOpt {
|
||||
filters?: string;
|
||||
}
|
||||
export interface LabelOpt {
|
||||
[key: string]: {
|
||||
[key: string]: boolean
|
||||
}
|
||||
}
|
||||
}
|
18
packages/docker-api/src/api/opts/container.ts
Normal file
18
packages/docker-api/src/api/opts/container.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import * as common from './common'
|
||||
|
||||
export declare namespace container {
|
||||
export interface ListOpts extends common.query.FilterOpt {
|
||||
all?: boolean;
|
||||
limit?: number;
|
||||
size?: boolean;
|
||||
}
|
||||
export interface LogsOpts {
|
||||
follow?: boolean;
|
||||
stdout?: boolean;
|
||||
stderr?: boolean;
|
||||
since?: number;
|
||||
until?: number;
|
||||
timestamps?: boolean;
|
||||
tail?: number | "all";
|
||||
}
|
||||
}
|
5
packages/docker-api/src/api/opts/index.ts
Normal file
5
packages/docker-api/src/api/opts/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './swarm'
|
||||
export * from './common'
|
||||
export * from './network'
|
||||
export * from './service'
|
||||
export * from './container'
|
6
packages/docker-api/src/api/opts/network.ts
Normal file
6
packages/docker-api/src/api/opts/network.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import * as common from './common'
|
||||
|
||||
export declare namespace network {
|
||||
export interface ListOpts extends common.query.FilterOpt {
|
||||
}
|
||||
}
|
6
packages/docker-api/src/api/opts/service.ts
Normal file
6
packages/docker-api/src/api/opts/service.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import * as common from './common'
|
||||
|
||||
export declare namespace service {
|
||||
export interface ListOpts extends common.query.FilterOpt {
|
||||
}
|
||||
}
|
59
packages/docker-api/src/api/opts/swarm.ts
Normal file
59
packages/docker-api/src/api/opts/swarm.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { Labels } from '../common'
|
||||
|
||||
export declare namespace swarm {
|
||||
type NodeAvailability = string;
|
||||
|
||||
export interface InitOpts {
|
||||
ListenAddr?: string;
|
||||
AdvertiseAddr?: string;
|
||||
DefaultAddrPool?: string[];
|
||||
DataPathAddr?: string;
|
||||
DataPathPort?: number;
|
||||
SubnetSize?: number;
|
||||
ForceNewCluster?: boolean;
|
||||
Availability?: NodeAvailability;
|
||||
Spec?: Spec;
|
||||
}
|
||||
|
||||
export interface Spec {
|
||||
Name?: string;
|
||||
Labels?: Labels;
|
||||
Orchestration?: Orchestration;
|
||||
Raft?: Raft;
|
||||
Dispatcher?: Dispatcher;
|
||||
CAConfig?: CAConfig;
|
||||
TaskDefaults?: TaskDefaults;
|
||||
EncryptionConfig?: EncryptionConfig;
|
||||
}
|
||||
|
||||
export interface Version {
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export interface Orchestration {
|
||||
TaskHistoryRetentionLimit?: number;
|
||||
}
|
||||
|
||||
export interface Raft {
|
||||
SnapshotInterval?: number;
|
||||
KeepOldSnapshots?: number;
|
||||
LogEntriesForSlowFollowers?: number;
|
||||
ElectionTick?: number;
|
||||
HeartbeatTick?: number;
|
||||
}
|
||||
|
||||
export interface Dispatcher {
|
||||
HeartbeatPeriod?: number;
|
||||
}
|
||||
|
||||
export interface CAConfig {
|
||||
NodeCertExpiry?: number;
|
||||
}
|
||||
|
||||
export interface TaskDefaults {
|
||||
}
|
||||
|
||||
export interface EncryptionConfig {
|
||||
AutoLockManagers?: boolean;
|
||||
}
|
||||
}
|
300
packages/docker-api/src/api/types/container.ts
Normal file
300
packages/docker-api/src/api/types/container.ts
Normal file
@ -0,0 +1,300 @@
|
||||
import { Labels, Config as CommonConfig, Ports, Options, StringMap, ObjectMap } from '../common'
|
||||
|
||||
export declare namespace container {
|
||||
export interface ContainerState {
|
||||
Status: string;
|
||||
Running: boolean;
|
||||
Paused: boolean;
|
||||
Restarting: boolean;
|
||||
OOMKilled: boolean;
|
||||
Dead: boolean;
|
||||
Pid: number;
|
||||
ExitCode: number;
|
||||
Error: string;
|
||||
StartedAt: string;
|
||||
FinishedAt: Date;
|
||||
}
|
||||
|
||||
export interface LogConfig {
|
||||
Type: string;
|
||||
Config: CommonConfig;
|
||||
}
|
||||
|
||||
export interface PortBindings {
|
||||
}
|
||||
|
||||
export interface RestartPolicy {
|
||||
Name: string;
|
||||
MaximumRetryCount: number;
|
||||
}
|
||||
|
||||
// WeightDevice is a structure that holds device:weight pair
|
||||
export interface WeightDevice {
|
||||
Path: string;
|
||||
Weight: number;
|
||||
}
|
||||
// ThrottleDevice is a structure that holds device:rate_per_second pair
|
||||
export interface ThrottleDevice {
|
||||
Path: string;
|
||||
Rate: number;
|
||||
}
|
||||
// DeviceMapping represents the device mapping between the host and the container.
|
||||
export interface DeviceMapping {
|
||||
PathOnHost: string;
|
||||
PathInContainer: string;
|
||||
CgroupPermissions: string;
|
||||
}
|
||||
// DeviceRequest represents a request for devices from a device driver.
|
||||
// Used by GPU device drivers.
|
||||
export interface DeviceRequest {
|
||||
Driver: string // Name of device driver
|
||||
Count: number // Number of devices to request (-1 = All)
|
||||
DeviceIDs: string[] // List of device IDs as recognizable by the device driver
|
||||
Capabilities: string[][] // An OR list of AND lists of device capabilities (e.g. "gpu")
|
||||
Options: StringMap // Options to pass onto the device driver
|
||||
}
|
||||
export interface Resources {
|
||||
CpuShares?: number;
|
||||
Memory?: number;
|
||||
NanoCpus?: number;
|
||||
CgroupParent?: string;
|
||||
BlkioWeight?: number;
|
||||
BlkioWeightDevice?: WeightDevice[];
|
||||
BlkioDeviceReadBps?: ThrottleDevice[];
|
||||
BlkioDeviceWriteBps?: ThrottleDevice[];
|
||||
BlkioDeviceReadIOps?: ThrottleDevice[];
|
||||
BlkioDeviceWriteIOps?: ThrottleDevice[];
|
||||
CpuPeriod?: number;
|
||||
CpuQuota?: number;
|
||||
CpuRealtimePeriod?: number;
|
||||
CpuRealtimeRuntime?: number;
|
||||
CpusetCpus?: string;
|
||||
CpusetMems?: string;
|
||||
Devices?: DeviceMapping[];
|
||||
DeviceCgroupRules?: string[];
|
||||
DeviceRequests: DeviceRequest[];
|
||||
DiskQuota?: number;
|
||||
KernelMemory?: number;
|
||||
MemoryReservation?: number;
|
||||
MemorySwap?: number;
|
||||
MemorySwappiness?: any;
|
||||
OomKillDisable?: boolean;
|
||||
PidsLimit?: number;
|
||||
Ulimits?: any;
|
||||
CpuCount?: number;
|
||||
CpuPercent?: number;
|
||||
IOMaximumIOps?: number;
|
||||
IOMaximumBandwidth?: number;
|
||||
}
|
||||
|
||||
export interface HostConfig extends Resources {
|
||||
Binds?: any;
|
||||
ContainerIDFile: string;
|
||||
LogConfig: LogConfig;
|
||||
NetworkMode: string;
|
||||
PortBindings: PortBindings;
|
||||
RestartPolicy: RestartPolicy;
|
||||
AutoRemove: boolean;
|
||||
VolumeDriver: string;
|
||||
VolumesFrom?: any;
|
||||
CapAdd?: any;
|
||||
CapDrop?: any;
|
||||
Dns?: any;
|
||||
DnsOptions?: any;
|
||||
DnsSearch?: any;
|
||||
ExtraHosts?: any;
|
||||
GroupAdd?: any;
|
||||
IpcMode: string;
|
||||
Cgroup: string;
|
||||
Links?: any;
|
||||
OomScoreAdj: number;
|
||||
PidMode: string;
|
||||
Privileged: boolean;
|
||||
PublishAllPorts: boolean;
|
||||
ReadonlyRootfs: boolean;
|
||||
SecurityOpt?: any;
|
||||
UTSMode: string;
|
||||
UsernsMode: string;
|
||||
ShmSize: number;
|
||||
Runtime: string;
|
||||
ConsoleSize: number[];
|
||||
Isolation: string;
|
||||
Mounts: Mount[];
|
||||
MaskedPaths: string[];
|
||||
ReadonlyPaths: string[];
|
||||
}
|
||||
|
||||
export interface Data {
|
||||
LowerDir: string;
|
||||
MergedDir: string;
|
||||
UpperDir: string;
|
||||
WorkDir: string;
|
||||
}
|
||||
|
||||
export interface GraphDriver {
|
||||
Data: Data;
|
||||
Name: string;
|
||||
}
|
||||
|
||||
export type ExposedPorts = Ports
|
||||
|
||||
// HealthConfig holds configuration settings for the HEALTHCHECK feature.
|
||||
export interface HealthConfig {
|
||||
// Test is the test to perform to check that the container is healthy.
|
||||
// An empty slice means to inherit the default.
|
||||
// The options are:
|
||||
// {} : inherit healthcheck
|
||||
// {"NONE"} : disable healthcheck
|
||||
// {"CMD", args...} : exec arguments directly
|
||||
// {"CMD-SHELL", command} : run command with system's default shell
|
||||
Test: string[];
|
||||
|
||||
// Zero means to inherit. Durations are expressed as integer nanoseconds.
|
||||
Interval: number; // Interval is the time to wait between checks.
|
||||
Timeout: number; // Timeout is the time to wait before considering the check to have hung.
|
||||
StartPeriod: number; // The start period for the container to initialize before the retries starts to count down.
|
||||
|
||||
// Retries is the number of consecutive failures needed to consider a container as unhealthy.
|
||||
// Zero means inherit.
|
||||
Retries: number;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
Hostname: string;
|
||||
Domainname: string;
|
||||
User: string;
|
||||
AttachStdin: boolean;
|
||||
AttachStdout: boolean;
|
||||
AttachStderr: boolean;
|
||||
ExposedPorts: ExposedPorts;
|
||||
Tty: boolean;
|
||||
OpenStdin: boolean;
|
||||
StdinOnce: boolean;
|
||||
Env: string[];
|
||||
Cmd?: any;
|
||||
Healthcheck?: HealthConfig;
|
||||
ArgsEscaped: boolean;
|
||||
Image: string;
|
||||
Volumes?: ObjectMap;
|
||||
WorkingDir: string;
|
||||
Entrypoint: string[];
|
||||
NetworkDisabled: boolean;
|
||||
MacAddress: string;
|
||||
OnBuild?: any;
|
||||
Labels: Labels;
|
||||
StopSignal: string;
|
||||
StopTimeout: number;
|
||||
Shell: string[];
|
||||
}
|
||||
|
||||
export interface IPAMConfig {
|
||||
IPv4Address: string;
|
||||
}
|
||||
|
||||
export interface Networks {
|
||||
[key: string]: Network
|
||||
}
|
||||
|
||||
export interface NetworkSettings {
|
||||
Bridge: string;
|
||||
SandboxID: string;
|
||||
HairpinMode: boolean;
|
||||
LinkLocalIPv6Address: string;
|
||||
LinkLocalIPv6PrefixLen: number;
|
||||
Ports: Ports;
|
||||
SandboxKey: string;
|
||||
SecondaryIPAddresses?: any;
|
||||
SecondaryIPv6Addresses?: any;
|
||||
EndpointID: string;
|
||||
Gateway: string;
|
||||
GlobalIPv6Address: string;
|
||||
GlobalIPv6PrefixLen: number;
|
||||
IPAddress: string;
|
||||
IPPrefixLen: number;
|
||||
IPv6Gateway: string;
|
||||
MacAddress: string;
|
||||
Networks: Networks;
|
||||
}
|
||||
|
||||
export interface ContainerJSON {
|
||||
Id: string;
|
||||
Created: string;
|
||||
Path: string;
|
||||
Args: string[];
|
||||
State: ContainerState;
|
||||
Image: string;
|
||||
ResolvConfPath: string;
|
||||
HostnamePath: string;
|
||||
HostsPath: string;
|
||||
LogPath: string;
|
||||
Name: string;
|
||||
RestartCount: number;
|
||||
Driver: string;
|
||||
Platform: string;
|
||||
MountLabel: string;
|
||||
ProcessLabel: string;
|
||||
AppArmorProfile: string;
|
||||
ExecIDs?: any;
|
||||
HostConfig: HostConfig;
|
||||
GraphDriver: GraphDriver;
|
||||
Mounts: Mount[];
|
||||
Config: Config;
|
||||
NetworkSettings: NetworkSettings;
|
||||
}
|
||||
|
||||
export interface Port {
|
||||
IP: string;
|
||||
PrivatePort: number;
|
||||
PublicPort: number;
|
||||
Type: string;
|
||||
}
|
||||
|
||||
export interface Network {
|
||||
IPAMConfig?: IPAMConfig;
|
||||
Links?: any;
|
||||
Aliases?: any;
|
||||
NetworkID: string;
|
||||
EndpointID: string;
|
||||
Gateway: string;
|
||||
IPAddress: string;
|
||||
IPPrefixLen: number;
|
||||
IPv6Gateway: string;
|
||||
GlobalIPv6Address: string;
|
||||
GlobalIPv6PrefixLen: number;
|
||||
MacAddress: string;
|
||||
DriverOpts?: any;
|
||||
}
|
||||
|
||||
export interface SummaryNetworkSettings {
|
||||
Networks: Networks;
|
||||
}
|
||||
|
||||
export interface Mount {
|
||||
Type: string;
|
||||
Name: string;
|
||||
Source: string;
|
||||
Destination: string;
|
||||
Driver: string;
|
||||
Mode: string;
|
||||
RW: boolean;
|
||||
Propagation: string;
|
||||
}
|
||||
|
||||
export interface Container {
|
||||
Id: string;
|
||||
Names: string[];
|
||||
Image: string;
|
||||
ImageID: string;
|
||||
Command: string;
|
||||
Created: number;
|
||||
Ports: Port[];
|
||||
Labels: Labels;
|
||||
State: string;
|
||||
Status: string;
|
||||
HostConfig: {
|
||||
NetworkMode: string;
|
||||
};
|
||||
NetworkSettings: SummaryNetworkSettings;
|
||||
Mounts: Mount[];
|
||||
}
|
||||
}
|
6
packages/docker-api/src/api/types/index.ts
Normal file
6
packages/docker-api/src/api/types/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export * from './node'
|
||||
export * from './swarm'
|
||||
export * from './system'
|
||||
export * from './network'
|
||||
export * from './service'
|
||||
export * from './container'
|
70
packages/docker-api/src/api/types/network.ts
Normal file
70
packages/docker-api/src/api/types/network.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { Labels, Options, StringMap } from '../common'
|
||||
|
||||
export declare namespace network {
|
||||
export interface Config {
|
||||
Subnet: string;
|
||||
Gateway: string;
|
||||
}
|
||||
|
||||
export interface IPAM {
|
||||
Driver: string;
|
||||
Options?: any;
|
||||
Config: Config[];
|
||||
}
|
||||
|
||||
export interface ConfigFrom {
|
||||
Network: string;
|
||||
}
|
||||
|
||||
export interface EndpointResource {
|
||||
Name: string;
|
||||
EndpointID: string;
|
||||
MacAddress: string;
|
||||
IPv4Address: string;
|
||||
IPv6Address: string;
|
||||
}
|
||||
|
||||
export interface Containers {
|
||||
[key: string]: EndpointResource;
|
||||
}
|
||||
|
||||
export interface PeerInfo {
|
||||
Name: string;
|
||||
IP: string;
|
||||
}
|
||||
|
||||
// Task carries the information about one backend task
|
||||
export interface Task {
|
||||
Name: string;
|
||||
EndpointID: string;
|
||||
EndpointIP: string;
|
||||
Info: StringMap;
|
||||
}
|
||||
|
||||
export interface ServiceInfo {
|
||||
VIP: string;
|
||||
Ports: string;
|
||||
LocalLBIndex: number;
|
||||
Tasks: Task;
|
||||
}
|
||||
|
||||
export interface NetworkResource {
|
||||
Name: string;
|
||||
Id: string;
|
||||
Created: string;
|
||||
Scope: string;
|
||||
Driver: string;
|
||||
EnableIPv6: boolean;
|
||||
IPAM: IPAM;
|
||||
Internal: boolean;
|
||||
Attachable: boolean;
|
||||
Ingress: boolean;
|
||||
ConfigFrom: ConfigFrom;
|
||||
ConfigOnly: boolean;
|
||||
Containers?: Containers;
|
||||
Options: Options;
|
||||
Labels: Labels;
|
||||
Peers: network.PeerInfo[];
|
||||
Services: network.ServiceInfo[];
|
||||
}
|
||||
}
|
71
packages/docker-api/src/api/types/node.ts
Normal file
71
packages/docker-api/src/api/types/node.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import { Labels } from '../common'
|
||||
|
||||
export declare namespace node {
|
||||
|
||||
export interface Version {
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export interface Spec {
|
||||
Labels: Labels;
|
||||
Role: string;
|
||||
Availability: string;
|
||||
}
|
||||
|
||||
export interface Platform {
|
||||
Architecture: string;
|
||||
OS: string;
|
||||
}
|
||||
|
||||
export interface Resources {
|
||||
NanoCPUs: number;
|
||||
MemoryBytes: number;
|
||||
}
|
||||
|
||||
export interface Plugin {
|
||||
Type: string;
|
||||
Name: string;
|
||||
}
|
||||
|
||||
export interface Engine {
|
||||
EngineVersion: string;
|
||||
Plugins: Plugin[];
|
||||
}
|
||||
|
||||
export interface TLSInfo {
|
||||
TrustRoot: string;
|
||||
CertIssuerSubject: string;
|
||||
CertIssuerPublicKey: string;
|
||||
}
|
||||
|
||||
export interface Description {
|
||||
Hostname: string;
|
||||
Platform: Platform;
|
||||
Resources: Resources;
|
||||
Engine: Engine;
|
||||
TLSInfo: TLSInfo;
|
||||
}
|
||||
|
||||
export interface Status {
|
||||
State: string;
|
||||
Addr: string;
|
||||
}
|
||||
|
||||
export interface ManagerStatus {
|
||||
Leader: boolean;
|
||||
Reachability: string;
|
||||
Addr: string;
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
ID: string;
|
||||
Version: Version;
|
||||
CreatedAt: string;
|
||||
UpdatedAt: string;
|
||||
Spec: Spec;
|
||||
Description: Description;
|
||||
Status: Status;
|
||||
ManagerStatus: ManagerStatus;
|
||||
}
|
||||
}
|
||||
|
195
packages/docker-api/src/api/types/service.ts
Normal file
195
packages/docker-api/src/api/types/service.ts
Normal file
@ -0,0 +1,195 @@
|
||||
import { Labels, Options } from '../common'
|
||||
|
||||
export declare namespace service {
|
||||
export interface Version {
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export interface Privileges {
|
||||
CredentialSpec?: any;
|
||||
SELinuxContext?: any;
|
||||
}
|
||||
|
||||
export interface DriverConfig {
|
||||
Options: Options;
|
||||
}
|
||||
|
||||
export interface VolumeOptions {
|
||||
Labels: Labels;
|
||||
DriverConfig: DriverConfig;
|
||||
}
|
||||
|
||||
export interface Mount {
|
||||
Type: string;
|
||||
Source: string;
|
||||
Target: string;
|
||||
VolumeOptions: VolumeOptions;
|
||||
ReadOnly?: boolean;
|
||||
}
|
||||
|
||||
export interface File {
|
||||
Name: string;
|
||||
UID: string;
|
||||
GID: string;
|
||||
Mode: number;
|
||||
}
|
||||
|
||||
export interface Secret {
|
||||
File: File;
|
||||
SecretID: string;
|
||||
SecretName: string;
|
||||
}
|
||||
|
||||
export interface DNSConfig {
|
||||
}
|
||||
|
||||
export interface ContainerSpec {
|
||||
Image: string;
|
||||
Labels: Labels;
|
||||
Privileges: Privileges;
|
||||
Mounts: Mount[];
|
||||
Isolation: string;
|
||||
Env: string[];
|
||||
Secrets: Secret[];
|
||||
Args: string[];
|
||||
StopGracePeriod?: number;
|
||||
DNSConfig: DNSConfig;
|
||||
User: string;
|
||||
}
|
||||
|
||||
export interface Limits {
|
||||
MemoryBytes: any;
|
||||
NanoCPUs?: number;
|
||||
}
|
||||
|
||||
export interface Reservations {
|
||||
MemoryBytes: any;
|
||||
NanoCPUs?: number;
|
||||
}
|
||||
|
||||
export interface Resources {
|
||||
Limits: Limits;
|
||||
Reservations: Reservations;
|
||||
}
|
||||
|
||||
export interface Platform {
|
||||
Architecture: string;
|
||||
OS: string;
|
||||
}
|
||||
|
||||
export interface Placement {
|
||||
Constraints: string[];
|
||||
Platforms: Platform[];
|
||||
}
|
||||
|
||||
export interface Network {
|
||||
Target: string;
|
||||
Aliases: string[];
|
||||
}
|
||||
|
||||
export interface RestartPolicy {
|
||||
Condition: string;
|
||||
Delay: any;
|
||||
MaxAttempts: number;
|
||||
Window: any;
|
||||
}
|
||||
|
||||
export interface LogDriver {
|
||||
Name: string;
|
||||
Options: Options;
|
||||
}
|
||||
|
||||
export interface TaskTemplate {
|
||||
ContainerSpec: ContainerSpec;
|
||||
Resources: Resources;
|
||||
Placement: Placement;
|
||||
Networks: Network[];
|
||||
ForceUpdate: number;
|
||||
Runtime: string;
|
||||
RestartPolicy: RestartPolicy;
|
||||
LogDriver: LogDriver;
|
||||
}
|
||||
|
||||
export interface Replicated {
|
||||
Replicas: number;
|
||||
}
|
||||
|
||||
export interface Global {
|
||||
}
|
||||
|
||||
export interface Mode {
|
||||
Replicated: Replicated;
|
||||
Global: Global;
|
||||
}
|
||||
|
||||
export interface Port {
|
||||
Protocol: string;
|
||||
TargetPort: number;
|
||||
PublishedPort: number;
|
||||
PublishMode: string;
|
||||
}
|
||||
|
||||
export interface EndpointSpec {
|
||||
Mode: string;
|
||||
Ports: Port[];
|
||||
}
|
||||
|
||||
export interface UpdateConfig {
|
||||
Parallelism: number;
|
||||
FailureAction: string;
|
||||
Monitor: number;
|
||||
MaxFailureRatio: number;
|
||||
Order: string;
|
||||
}
|
||||
|
||||
export interface RollbackConfig {
|
||||
Parallelism: number;
|
||||
FailureAction: string;
|
||||
Monitor: number;
|
||||
MaxFailureRatio: number;
|
||||
Order: string;
|
||||
}
|
||||
|
||||
export interface Spec {
|
||||
Name: string;
|
||||
Labels: Labels;
|
||||
TaskTemplate: TaskTemplate;
|
||||
Mode: Mode;
|
||||
EndpointSpec: EndpointSpec;
|
||||
UpdateConfig: UpdateConfig;
|
||||
RollbackConfig: RollbackConfig;
|
||||
}
|
||||
|
||||
export interface VirtualIP {
|
||||
NetworkID: string;
|
||||
Addr: string;
|
||||
}
|
||||
|
||||
export interface Endpoint {
|
||||
Spec: Spec;
|
||||
Ports: Port[];
|
||||
VirtualIPs: VirtualIP[];
|
||||
}
|
||||
|
||||
export interface PreviousSpec {
|
||||
Name: string;
|
||||
Labels: Labels;
|
||||
TaskTemplate: TaskTemplate;
|
||||
Mode: Mode;
|
||||
EndpointSpec: EndpointSpec;
|
||||
UpdateConfig: UpdateConfig;
|
||||
RollbackConfig: RollbackConfig;
|
||||
}
|
||||
|
||||
export interface Service {
|
||||
ID: string;
|
||||
Version: Version;
|
||||
CreatedAt: string;
|
||||
UpdatedAt: any;
|
||||
Spec: Spec;
|
||||
Endpoint: Endpoint;
|
||||
PreviousSpec: PreviousSpec;
|
||||
}
|
||||
|
||||
}
|
||||
|
70
packages/docker-api/src/api/types/swarm.ts
Normal file
70
packages/docker-api/src/api/types/swarm.ts
Normal file
@ -0,0 +1,70 @@
|
||||
export declare namespace swarm {
|
||||
export interface Version {
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export interface Labels {
|
||||
}
|
||||
|
||||
export interface Orchestration {
|
||||
TaskHistoryRetentionLimit?: number;
|
||||
}
|
||||
|
||||
export interface Raft {
|
||||
SnapshotInterval?: number;
|
||||
KeepOldSnapshots?: number;
|
||||
LogEntriesForSlowFollowers?: number;
|
||||
ElectionTick?: number;
|
||||
HeartbeatTick?: number;
|
||||
}
|
||||
|
||||
export interface Dispatcher {
|
||||
HeartbeatPeriod?: number;
|
||||
}
|
||||
|
||||
export interface CAConfig {
|
||||
NodeCertExpiry?: number;
|
||||
}
|
||||
|
||||
export interface TaskDefaults {
|
||||
}
|
||||
|
||||
export interface EncryptionConfig {
|
||||
AutoLockManagers?: boolean;
|
||||
}
|
||||
|
||||
export interface Spec {
|
||||
Name?: string;
|
||||
Labels?: Labels;
|
||||
Orchestration?: Orchestration;
|
||||
Raft?: Raft;
|
||||
Dispatcher?: Dispatcher;
|
||||
CAConfig?: CAConfig;
|
||||
TaskDefaults?: TaskDefaults;
|
||||
EncryptionConfig?: EncryptionConfig;
|
||||
}
|
||||
|
||||
export interface TLSInfo {
|
||||
TrustRoot: string;
|
||||
CertIssuerSubject: string;
|
||||
CertIssuerPublicKey: string;
|
||||
}
|
||||
|
||||
export interface JoinTokens {
|
||||
Worker: string;
|
||||
Manager: string;
|
||||
}
|
||||
|
||||
export interface Info {
|
||||
ID: string;
|
||||
Version: Version;
|
||||
CreatedAt: string;
|
||||
UpdatedAt: string;
|
||||
Spec: Spec;
|
||||
TLSInfo: TLSInfo;
|
||||
RootRotationInProgress: boolean;
|
||||
DefaultAddrPool: string[];
|
||||
SubnetSize: number;
|
||||
JoinTokens: JoinTokens;
|
||||
}
|
||||
}
|
224
packages/docker-api/src/api/types/system.ts
Normal file
224
packages/docker-api/src/api/types/system.ts
Normal file
@ -0,0 +1,224 @@
|
||||
import { Labels, Options } from '../common'
|
||||
|
||||
export declare namespace system {
|
||||
export class Plugins {
|
||||
Volume: string[];
|
||||
Network: string[];
|
||||
Authorization?: any;
|
||||
Log: string[];
|
||||
}
|
||||
|
||||
export class DockerIo {
|
||||
Name: string;
|
||||
Mirrors: string[];
|
||||
Secure: boolean;
|
||||
Official: boolean;
|
||||
}
|
||||
|
||||
export class IndexConfigs {
|
||||
[key: string]: DockerIo;
|
||||
}
|
||||
|
||||
export class RegistryConfig {
|
||||
AllowNondistributableArtifactsCIDRs: any[];
|
||||
AllowNondistributableArtifactsHostnames: any[];
|
||||
InsecureRegistryCIDRs: string[];
|
||||
IndexConfigs: IndexConfigs;
|
||||
Mirrors: string[];
|
||||
}
|
||||
|
||||
export class Runc {
|
||||
path: string;
|
||||
}
|
||||
|
||||
export class Runtimes {
|
||||
runc: Runc;
|
||||
}
|
||||
|
||||
export class RemoteManager {
|
||||
NodeID: string;
|
||||
Addr: string;
|
||||
}
|
||||
|
||||
export class ClusterVersion {
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export class Orchestration {
|
||||
TaskHistoryRetentionLimit: number;
|
||||
}
|
||||
|
||||
export class Raft {
|
||||
SnapshotInterval: number;
|
||||
KeepOldSnapshots: number;
|
||||
LogEntriesForSlowFollowers: number;
|
||||
ElectionTick: number;
|
||||
HeartbeatTick: number;
|
||||
}
|
||||
|
||||
export class Dispatcher {
|
||||
HeartbeatPeriod: number;
|
||||
}
|
||||
|
||||
export class CAConfig {
|
||||
NodeCertExpiry: number;
|
||||
}
|
||||
|
||||
export class TaskDefaults {
|
||||
}
|
||||
|
||||
export class EncryptionConfig {
|
||||
AutoLockManagers: boolean;
|
||||
}
|
||||
|
||||
export class Spec {
|
||||
Name: string;
|
||||
Labels: Labels;
|
||||
Orchestration: Orchestration;
|
||||
Raft: Raft;
|
||||
Dispatcher: Dispatcher;
|
||||
CAConfig: CAConfig;
|
||||
TaskDefaults: TaskDefaults;
|
||||
EncryptionConfig: EncryptionConfig;
|
||||
}
|
||||
|
||||
export class TLSInfo {
|
||||
TrustRoot: string;
|
||||
CertIssuerSubject: string;
|
||||
CertIssuerPublicKey: string;
|
||||
}
|
||||
|
||||
export class Cluster {
|
||||
ID: string;
|
||||
Version: ClusterVersion;
|
||||
CreatedAt: string;
|
||||
UpdatedAt: string;
|
||||
Spec: Spec;
|
||||
TLSInfo: TLSInfo;
|
||||
RootRotationInProgress: boolean;
|
||||
DefaultAddrPool: string[];
|
||||
SubnetSize: number;
|
||||
}
|
||||
|
||||
export class Swarm {
|
||||
NodeID: string;
|
||||
NodeAddr: string;
|
||||
LocalNodeState: string;
|
||||
ControlAvailable: boolean;
|
||||
Error: string;
|
||||
RemoteManagers: RemoteManager[];
|
||||
Nodes: number;
|
||||
Managers: number;
|
||||
Cluster: Cluster;
|
||||
}
|
||||
|
||||
export class ContainerdCommit {
|
||||
ID: string;
|
||||
Expected: string;
|
||||
}
|
||||
|
||||
export class RuncCommit {
|
||||
ID: string;
|
||||
Expected: string;
|
||||
}
|
||||
|
||||
export class InitCommit {
|
||||
ID: string;
|
||||
Expected: string;
|
||||
}
|
||||
|
||||
export class Info {
|
||||
ID: string;
|
||||
Containers: number;
|
||||
ContainersRunning: number;
|
||||
ContainersPaused: number;
|
||||
ContainersStopped: number;
|
||||
Images: number;
|
||||
Driver: string;
|
||||
DriverStatus: string[][];
|
||||
SystemStatus?: any;
|
||||
Plugins: Plugins;
|
||||
MemoryLimit: boolean;
|
||||
SwapLimit: boolean;
|
||||
KernelMemory: boolean;
|
||||
CpuCfsPeriod: boolean;
|
||||
CpuCfsQuota: boolean;
|
||||
CPUShares: boolean;
|
||||
CPUSet: boolean;
|
||||
IPv4Forwarding: boolean;
|
||||
BridgeNfIptables: boolean;
|
||||
BridgeNfIp6tables: boolean;
|
||||
Debug: boolean;
|
||||
NFd: number;
|
||||
OomKillDisable: boolean;
|
||||
NGoroutines: number;
|
||||
SystemTime: string;
|
||||
LoggingDriver: string;
|
||||
CgroupDriver: string;
|
||||
NEventsListener: number;
|
||||
KernelVersion: string;
|
||||
OperatingSystem: string;
|
||||
OSType: string;
|
||||
Architecture: string;
|
||||
IndexServerAddress: string;
|
||||
RegistryConfig: RegistryConfig;
|
||||
NCPU: number;
|
||||
MemTotal: number;
|
||||
GenericResources?: any;
|
||||
DockerRootDir: string;
|
||||
HttpProxy: string;
|
||||
HttpsProxy: string;
|
||||
NoProxy: string;
|
||||
Name: string;
|
||||
Labels: string[];
|
||||
ExperimentalBuild: boolean;
|
||||
ServerVersion: string;
|
||||
ClusterStore: string;
|
||||
ClusterAdvertise: string;
|
||||
Runtimes: Runtimes;
|
||||
DefaultRuntime: string;
|
||||
Swarm: Swarm;
|
||||
LiveRestoreEnabled: boolean;
|
||||
Isolation: string;
|
||||
InitBinary: string;
|
||||
ContainerdCommit: ContainerdCommit;
|
||||
RuncCommit: RuncCommit;
|
||||
InitCommit: InitCommit;
|
||||
SecurityOptions: string[];
|
||||
ProductLicense: string;
|
||||
Warnings?: any;
|
||||
}
|
||||
|
||||
export class Platform {
|
||||
Name: string;
|
||||
}
|
||||
export class Details {
|
||||
ApiVersion: string;
|
||||
Arch: string;
|
||||
BuildTime: string;
|
||||
Experimental: string;
|
||||
GitCommit: string;
|
||||
GoVersion: string;
|
||||
KernelVersion: string;
|
||||
MinAPIVersion: string;
|
||||
Os: string;
|
||||
}
|
||||
export class Component {
|
||||
Name: string;
|
||||
Version: string;
|
||||
Details: Details;
|
||||
}
|
||||
export class Version {
|
||||
Platform: Platform;
|
||||
Components: Component[];
|
||||
Version: string;
|
||||
ApiVersion: string;
|
||||
MinAPIVersion: string;
|
||||
GitCommit: string;
|
||||
GoVersion: string;
|
||||
Os: string;
|
||||
Arch: string;
|
||||
KernelVersion: string;
|
||||
BuildTime: string;
|
||||
}
|
||||
}
|
23
packages/docker-api/src/client/container.ts
Normal file
23
packages/docker-api/src/client/container.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import * as api from '../utils/api';
|
||||
import * as opts from '../api/opts'
|
||||
import * as types from '../api/types'
|
||||
import * as http from 'http'
|
||||
|
||||
export namespace container {
|
||||
export async function list(filters?: opts.container.ListOpts) {
|
||||
return await api.get<types.container.Container[]>('/containers/json', filters)
|
||||
}
|
||||
|
||||
export async function info(id: string, query: { size: boolean } = { size: false }) {
|
||||
return await api.get<types.container.ContainerJSON>(`/containers/${id}/json`, query);
|
||||
}
|
||||
|
||||
export async function logs(id: string, opts: opts.container.LogsOpts = {}): Promise<http.ServerResponse> {
|
||||
return await api.stream(`/containers/${id}/logs`, Object.assign({
|
||||
follow: true,
|
||||
stdout: true,
|
||||
stderr: true,
|
||||
tail: 10
|
||||
}, opts));
|
||||
}
|
||||
}
|
6
packages/docker-api/src/client/index.ts
Normal file
6
packages/docker-api/src/client/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export * from './node'
|
||||
export * from './swarm'
|
||||
export * from './system'
|
||||
export * from './network'
|
||||
export * from './service'
|
||||
export * from './container'
|
9
packages/docker-api/src/client/network.ts
Normal file
9
packages/docker-api/src/client/network.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import * as api from '../utils/api'
|
||||
import * as opts from '../api/opts'
|
||||
import * as types from '../api/types'
|
||||
|
||||
export namespace network {
|
||||
export async function list(opts?: opts.network.ListOpts) {
|
||||
return await api.get<types.network.NetworkResource[]>('/networks', opts)
|
||||
}
|
||||
}
|
8
packages/docker-api/src/client/node.ts
Normal file
8
packages/docker-api/src/client/node.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import * as api from '../utils/api'
|
||||
import * as types from '../api/types'
|
||||
|
||||
export namespace node {
|
||||
export async function list() {
|
||||
return await api.get<types.node.Node[]>('/nodes');
|
||||
}
|
||||
}
|
9
packages/docker-api/src/client/service.ts
Normal file
9
packages/docker-api/src/client/service.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import * as api from '../utils/api';
|
||||
import * as opts from '../api/opts';
|
||||
import * as types from '../api/types';
|
||||
|
||||
export namespace service {
|
||||
export async function list(filters?: opts.service.ListOpts) {
|
||||
return await api.get<types.service.Service[]>('/services', filters);
|
||||
}
|
||||
}
|
13
packages/docker-api/src/client/swarm.ts
Normal file
13
packages/docker-api/src/client/swarm.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import * as api from '../utils/api'
|
||||
import * as opts from '../api/opts'
|
||||
import * as types from '../api/types'
|
||||
|
||||
export namespace swarm {
|
||||
export async function inspect() {
|
||||
return await api.get<types.swarm.Info>('/swarm');
|
||||
}
|
||||
|
||||
export async function init(opts: opts.swarm.InitOpts) {
|
||||
return await api.post<string>('/swarm/init', opts);
|
||||
}
|
||||
}
|
22
packages/docker-api/src/client/system.ts
Normal file
22
packages/docker-api/src/client/system.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import * as api from '../utils/api'
|
||||
import * as types from '../api/types'
|
||||
|
||||
export namespace system {
|
||||
export async function info() {
|
||||
return await api.get<types.system.Info>('/info');
|
||||
}
|
||||
|
||||
export async function version() {
|
||||
return await api.get<types.system.Version>('/version');
|
||||
}
|
||||
|
||||
export async function events(cb: (events: object) => void) {
|
||||
let stream = await api.stream<any>('/events');
|
||||
stream.on('data', (chunk: ArrayBuffer) => {
|
||||
cb(JSON.parse(Buffer.from(chunk).toString()))
|
||||
})
|
||||
stream.on('end', () => {
|
||||
cb(undefined);
|
||||
})
|
||||
}
|
||||
}
|
1
packages/docker-api/src/index.ts
Normal file
1
packages/docker-api/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './client'
|
78
packages/docker-api/src/utils/api.ts
Normal file
78
packages/docker-api/src/utils/api.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import * as http from 'http'
|
||||
import axios, { AxiosResponse, AxiosRequestConfig, Method, AxiosInstance } from 'axios'
|
||||
|
||||
let api: AxiosInstance;
|
||||
|
||||
export async function get<T>(path: string, data?: object): Promise<T> {
|
||||
return await handle<T>("GET", path, { params: data });
|
||||
}
|
||||
|
||||
export async function post<T>(path: string, data?: object): Promise<T> {
|
||||
return await handle<T>("POST", path, { data });
|
||||
}
|
||||
|
||||
export async function stream<T = http.ServerResponse>(path: string, data?: object): Promise<T> {
|
||||
return await handle<T>("GET", path, { params: data, responseType: "stream" });
|
||||
}
|
||||
|
||||
async function handle<T>(method: Method, path: string, reqConfig?: AxiosRequestConfig): Promise<T> {
|
||||
let config: AxiosRequestConfig = {
|
||||
method,
|
||||
url: path,
|
||||
};
|
||||
let startTime = Date.now();
|
||||
Object.assign(config, reqConfig)
|
||||
let response: AxiosResponse;
|
||||
try {
|
||||
response = await api.request(config);
|
||||
return response.data as T
|
||||
} catch (ex) {
|
||||
if (!ex.response) { throw ex; }
|
||||
response = ex.response;
|
||||
if (response.status > 299 && config.responseType == "stream") {
|
||||
let stream = response.data;
|
||||
response.data = await new Promise<T>((resolve, reject) => {
|
||||
let cache = '';
|
||||
stream.on('data', (chunk: ArrayBuffer) => {
|
||||
cache += chunk.toString()
|
||||
})
|
||||
stream.on('end', () => {
|
||||
resolve(JSON.parse(cache) as T);
|
||||
})
|
||||
})
|
||||
}
|
||||
throw new Error(JSON.stringify(response.data));
|
||||
} finally {
|
||||
if (response) {
|
||||
console.log(`========== Docker API Invoke ==========
|
||||
REQUEST METHOD : ${method}
|
||||
REQUEST PATH : ${response.request.path}
|
||||
REQUEST PARAMS : ${config.params ? JSON.stringify(config.params) : ''}
|
||||
REQUEST BODY : ${config.data ? JSON.stringify(config.data) : ''}
|
||||
RESPONSE BODY : ${toString.call(response.data.pipe) === "[object Function]" ? '<Stream>' : JSON.stringify(response.data)}
|
||||
HANDLE TIME : ${Date.now() - startTime}ms
|
||||
=======================================`);
|
||||
}
|
||||
// console.log(`${method} ${path} HTTP/1.1
|
||||
// ${config.data ? JSON.stringify(config.data, null, 2) + '\n' : ''}
|
||||
// HTTP/1.1 ${response.status} ${response.statusText}
|
||||
// ${config.responseType != 'stream' ? JSON.stringify(response.data, null, 2) : config.responseType}`);
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
const instanceConfig: AxiosRequestConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 5000
|
||||
}
|
||||
if (process.env.DOCKER_HOST.startsWith("/")) {
|
||||
instanceConfig.socketPath = process.env.DOCKER_HOST
|
||||
} else {
|
||||
instanceConfig.baseURL = process.env.DOCKER_HOST
|
||||
}
|
||||
api = axios.create(instanceConfig)
|
||||
}
|
||||
|
||||
init();
|
3
packages/docker-api/src/utils/utils.ts
Normal file
3
packages/docker-api/src/utils/utils.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function Filters2String(filters: any) {
|
||||
|
||||
}
|
7
packages/docker-api/tsconfig.json
Normal file
7
packages/docker-api/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"outDir": "dist"
|
||||
}
|
||||
}
|
4
packages/faas/.gitignore
vendored
Normal file
4
packages/faas/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/node_modules
|
||||
/dist
|
||||
/package-lock.json
|
||||
/yarn.lock
|
22
packages/faas/.npmignore
Normal file
22
packages/faas/.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/faas/README.md
Normal file
11
packages/faas/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# `@dayu/faas`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
const core = require('@dayu/faas');
|
||||
|
||||
// TODO: DEMONSTRATE API
|
||||
```
|
27
packages/faas/package.json
Normal file
27
packages/faas/package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@dayu/faas",
|
||||
"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 src/index.ts",
|
||||
"clean": "rimraf dist",
|
||||
"watch": "npx tsc --watch",
|
||||
"build": "yarn clean && npx tsc",
|
||||
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.3",
|
||||
"ts-node-dev": "^1.0.0-pre.40",
|
||||
"typescript": "^3.5.2"
|
||||
}
|
||||
}
|
28
packages/faas/public/index.html
Normal file
28
packages/faas/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/faas/public/js/index.js
Normal file
68
packages/faas/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');
|
||||
});
|
26
packages/faas/src/api.ts
Normal file
26
packages/faas/src/api.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as faas from './interfaces'
|
||||
import axios, { AxiosRequestConfig } from 'axios'
|
||||
|
||||
const instanceConfig: AxiosRequestConfig = {
|
||||
baseURL: 'https://faas.yumc.pw',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Basic YWRtaW46MmQ2MzdiYzQ4MWQxYThhMjg2M2E2ZTIzOTY1ZWRlNDI0ZTRjMTk2OTQyMzU5N2M5MzRlNGQyY2FlZTNkMjk2OA=='
|
||||
},
|
||||
timeout: 5000
|
||||
}
|
||||
|
||||
let api = axios.create(instanceConfig)
|
||||
|
||||
async function get<T>(path: string) {
|
||||
let result = await api.get(path);
|
||||
return result.data as T;
|
||||
}
|
||||
|
||||
export async function getFunctions() {
|
||||
return await get<faas.Function[]>('/system/functions');
|
||||
}
|
||||
|
||||
export async function getFunction(name: string) {
|
||||
return await get<faas.Function>(`/system/function/${name}`);
|
||||
}
|
1
packages/faas/src/index.ts
Normal file
1
packages/faas/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './api'
|
13
packages/faas/src/interfaces.ts
Normal file
13
packages/faas/src/interfaces.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export interface Labels {
|
||||
[key: string]: string
|
||||
}
|
||||
export interface Function {
|
||||
name: string;
|
||||
image: string;
|
||||
invocationCount: number;
|
||||
replicas: number;
|
||||
envProcess: string;
|
||||
availableReplicas: number;
|
||||
labels: Labels;
|
||||
annotations?: any;
|
||||
}
|
7
packages/faas/tsconfig.json
Normal file
7
packages/faas/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"outDir": "dist"
|
||||
}
|
||||
}
|
4
packages/vscode/.gitignore
vendored
Normal file
4
packages/vscode/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
out
|
||||
node_modules
|
||||
.vscode-test/
|
||||
*.vsix
|
7
packages/vscode/.vscode/extensions.json
vendored
Normal file
7
packages/vscode/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"ms-vscode.vscode-typescript-tslint-plugin"
|
||||
]
|
||||
}
|
35
packages/vscode/.vscode/launch.json
vendored
Normal file
35
packages/vscode/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [{
|
||||
"name": "Run Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "npm: watch"
|
||||
},
|
||||
{
|
||||
"name": "Extension Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}",
|
||||
"--extensionTestsPath=${workspaceFolder}/out/test"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/test/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "npm: watch"
|
||||
}
|
||||
]
|
||||
}
|
12
packages/vscode/.vscode/settings.json
vendored
Normal file
12
packages/vscode/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.exclude": {
|
||||
"out": false // set this to true to hide the "out" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true // set this to false to include "out" folder in search results
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
20
packages/vscode/.vscode/tasks.json
vendored
Normal file
20
packages/vscode/.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
10
packages/vscode/.vscodeignore
Normal file
10
packages/vscode/.vscodeignore
Normal file
@ -0,0 +1,10 @@
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
out/test/**
|
||||
src/**
|
||||
.gitignore
|
||||
vsc-extension-quickstart.md
|
||||
**/tsconfig.json
|
||||
**/tslint.json
|
||||
**/*.map
|
||||
**/*.ts
|
9
packages/vscode/CHANGELOG.md
Normal file
9
packages/vscode/CHANGELOG.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to the "faas" extension will be documented in this file.
|
||||
|
||||
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Initial release
|
65
packages/vscode/README.md
Normal file
65
packages/vscode/README.md
Normal file
@ -0,0 +1,65 @@
|
||||
# faas README
|
||||
|
||||
This is the README for your extension "faas". After writing up a brief description, we recommend including the following sections.
|
||||
|
||||
## Features
|
||||
|
||||
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.
|
||||
|
||||
For example if there is an image subfolder under your extension project workspace:
|
||||
|
||||
\!\[feature X\]\(images/feature-x.png\)
|
||||
|
||||
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow.
|
||||
|
||||
## Requirements
|
||||
|
||||
If you have any requirements or dependencies, add a section describing those and how to install and configure them.
|
||||
|
||||
## Extension Settings
|
||||
|
||||
Include if your extension adds any VS Code settings through the `contributes.configuration` extension point.
|
||||
|
||||
For example:
|
||||
|
||||
This extension contributes the following settings:
|
||||
|
||||
* `myExtension.enable`: enable/disable this extension
|
||||
* `myExtension.thing`: set to `blah` to do something
|
||||
|
||||
## Known Issues
|
||||
|
||||
Calling out known issues can help limit users opening duplicate issues against your extension.
|
||||
|
||||
## Release Notes
|
||||
|
||||
Users appreciate release notes as you update your extension.
|
||||
|
||||
### 1.0.0
|
||||
|
||||
Initial release of ...
|
||||
|
||||
### 1.0.1
|
||||
|
||||
Fixed issue #.
|
||||
|
||||
### 1.1.0
|
||||
|
||||
Added features X, Y, and Z.
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
## Working with Markdown
|
||||
|
||||
**Note:** You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts:
|
||||
|
||||
* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux)
|
||||
* Toggle preview (`Shift+CMD+V` on macOS or `Shift+Ctrl+V` on Windows and Linux)
|
||||
* Press `Ctrl+Space` (Windows, Linux) or `Cmd+Space` (macOS) to see a list of Markdown snippets
|
||||
|
||||
### For more information
|
||||
|
||||
* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown)
|
||||
* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/)
|
||||
|
||||
**Enjoy!**
|
76
packages/vscode/package.json
Normal file
76
packages/vscode/package.json
Normal file
@ -0,0 +1,76 @@
|
||||
{
|
||||
"name": "@dayu/vscode",
|
||||
"displayName": "vscode",
|
||||
"description": "",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"vscode": "^1.35.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onCommand:extension.helloWorld"
|
||||
],
|
||||
"main": "./dist/extension.js",
|
||||
"contributes": {
|
||||
"viewsContainers": {
|
||||
"activitybar": [
|
||||
{
|
||||
"id": "dayu-explorer",
|
||||
"title": "Dayu Explorer",
|
||||
"icon": "src/images/logo.svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"views": {
|
||||
"dayu-explorer": [
|
||||
{
|
||||
"id": "docker-explorer",
|
||||
"name": "Docker"
|
||||
},
|
||||
{
|
||||
"id": "openfaas-explorer",
|
||||
"name": "OpenFaaS"
|
||||
}
|
||||
]
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"command": "dayu.container.logs",
|
||||
"title": "View Container Logs",
|
||||
"icon": {
|
||||
"dark": "src/images/browser.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"view/item/context": [
|
||||
{
|
||||
"command": "dayu.container.logs",
|
||||
"when": "view == docker-explorer && viewItem =~ /.*\"type\":\"CONTAINER\".*/",
|
||||
"group": "inline"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "yarn run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"postinstall": "node ../../node_modules/vscode/bin/install",
|
||||
"test": "yarn run compile && node ./node_modules/vscode/bin/test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dayu/docker-api": "^0.0.1",
|
||||
"@dayu/faas": "^0.0.1",
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "^10.12.21",
|
||||
"tslint": "^5.12.1",
|
||||
"typescript": "^3.3.1",
|
||||
"vscode": "^1.1.28"
|
||||
}
|
||||
}
|
15
packages/vscode/src/extension.ts
Normal file
15
packages/vscode/src/extension.ts
Normal file
@ -0,0 +1,15 @@
|
||||
// The module 'vscode' contains the VS Code extensibility API
|
||||
// Import the module and reference it with the alias vscode in your code below
|
||||
import * as vscode from 'vscode';
|
||||
process.env.DOCKER_HOST = '/var/run/docker.sock'
|
||||
import { OpenFaasProvider, DockerProvider } from './provider'
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
new DockerProvider(context);
|
||||
new OpenFaasProvider(context);
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate() { }
|
1
packages/vscode/src/images/browser.svg
Normal file
1
packages/vscode/src/images/browser.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16.08108103275299" height="16.540540516376495" style=""><rect id="backgroundrect" width="100%" height="100%" x="0" y="0" fill="none" stroke="none" style="" class=""/><g class="currentLayer" style=""><title>Layer 1</title><path d="M11.542335271835327,3.076456665992737 H3.147498369216919 C2.6127313375473022,3.076456665992737 2.178863525390625,3.526281714439392 2.178863525390625,4.080699563026428 v7.364412307739258 c0,0.5544231534004211 0.4338677227497101,1.0042381286621094 0.9686350226402283,1.0042381286621094 h8.394837379455566 c0.534767210483551,0 0.9686350226402283,-0.44981494545936584 0.9686350226402283,-1.0042381286621094 V4.080699563026428 c0,-0.5544231534004211 -0.4338677227497101,-1.0042381286621094 -0.9686350226402283,-1.0042381286621094 zM2.824620246887207,4.080699563026428 c0,-0.18411031365394592 0.14529526233673096,-0.33474603295326233 0.322878360748291,-0.33474603295326233 h0.9686350226402283 v1.3389841318130493 H2.824620246887207 V4.080699563026428 zm9.040594100952148,7.364412307739258 c0,0.18411031365394592 -0.14529526233673096,0.33474603295326233 -0.322878360748291,0.33474603295326233 H3.147498369216919 c-0.17758308351039886,0 -0.322878360748291,-0.1506357043981552 -0.322878360748291,-0.33474603295326233 V5.754433751106262 h9.040594100952148 v5.690682888031006 zm0,-6.360174655914307 H4.761890172958374 V3.745947003364563 h6.780445098876953 c0.17758308351039886,0 0.322878360748291,0.1506357043981552 0.322878360748291,0.33474603295326233 v1.0042381286621094 z" id="svg_1" class="selected" transform="translate(0.540541, 0.27027)" fill="#ffffff" fill-opacity="1"/></g></svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
packages/vscode/src/images/centos.svg
Normal file
1
packages/vscode/src/images/centos.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80"><path fill="#FFF" d="M75.438 39.65L65.295 29.504V14.53H50.738L40.77 4.56 40.21 4 29.68 14.53H14.53v15.15L4 40.21l10.53 10.53v14.555h14.975L39.65 75.44l.56.56 10.706-10.705h14.38v-14.38L75.44 40.772l.56-.56-.562-.56zm-11.73-23.534v11.802l-3.983-3.983-.562-.562-.562.562-12.815 12.817h-2.713v-1.94l13.412-13.415.562-.562-.562-.562-4.157-4.16h11.38v.003zm0 14.047v6.59h-15.68l11.135-11.135 4.544 4.545zM42.887 40.77l.712.714h-2.115V43.6l-1.273-1.273-1.87 1.87v-2.712h-1.94l1.273-1.273-1.87-1.87h2.537v-2.538l1.31 1.31.56.562.563-.56.713-.714v1.94H44.2l-1.308 1.31-.562.562.56.557zm11.915-19.934l-11.73 11.73v-16.45h7.01l4.72 4.72zM40.21 6.246l8.284 8.283h-7.01v19.624l-1.274 1.274-1.87-1.87v-19.03h-6.414l8.284-8.283zm-9.872 9.87h6.414V31.97L25.62 20.836l4.718-4.72zm-14.22 0h11.976l-4.72 4.72.56.563 12.818 12.816v2.537h-2.538l-13.378-13.38-4.72 4.72V16.118zm0 14.222l4.72-4.72L31.97 36.752H16.117v-6.414zm-1.59 18.157L6.246 40.21l8.285-8.285v6.414h19.028l1.87 1.87-1.273 1.272H14.53v7.013zm1.588-5.423h16.45l-11.73 11.73-4.72-4.722v-7.008zm0 20.635v-11.38l4.16 4.16.562.56.56-.56L34.814 43.07h1.94v2.713L23.935 58.602l-.56.562.56.562 3.983 3.98h-11.8zm9.503-4.544L36.752 48.03v15.677h-6.59l-4.544-4.544zm14.59 14.592l-8.46-8.46h6.59V46.44l1.87-1.868 1.274 1.272v19.45h7.186l-8.46 8.46zm10.048-10.048h-7.186V47.434l11.73 11.73-4.544 4.543zm13.45 0H52.502l4.544-4.543-.562-.562-13.413-13.414v-2.115h2.115L58.6 56.487l.562.562 4.545-4.546v11.203zm0-13.45l-4.545 4.546-11.73-11.73h16.274v7.185zm1.587-1.587v-7.186h-19.45l-1.272-1.273 1.87-1.87h18.854v-6.59l8.46 8.46-8.462 8.46z"/></svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
packages/vscode/src/images/docker-swarm.svg
Normal file
1
packages/vscode/src/images/docker-swarm.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" height="512" viewBox="0 0 1489 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M1465.995636 345.832727c-57.064727-38.818909-123.904-39.656727-168.122181-34.164363-21.876364-92.066909-105.192727-144.197818-109.288728-146.711273l-31.464727-19.269818-22.528 29.323636c-71.121455 92.718545-52.317091 193.629091-22.248727 255.720727a185.250909 185.250909 0 0 1-75.031273 20.48h-25.227636V298.449455h-172.218182V0.186182H632.087273v149.131636H291.374545v149.038546h-170.356363v152.855272H9.588364l-5.213091 35.002182c-1.210182 7.912727-27.927273 195.304727 96.628363 340.433455 91.136 106.123636 236.730182 159.930182 432.779637 159.930182 302.824727 0 488.913455-133.678545 591.592727-245.76a769.675636 769.675636 0 0 0 141.312-218.577455c189.719273-3.258182 215.505455-129.210182 216.529455-134.888727l4.933818-26.437818-22.248728-15.080728zM691.665455 297.797818v-88.715636h88.622545v88.715636H691.665455zM350.952727 446.836364v-88.715637h88.529455V446.836364H350.952727z m170.356364 0v-88.715637h88.529454V446.836364h-88.436363z m170.356364 0v-88.715637h88.622545V446.836364H691.665455z m172.218181-88.715637h88.436364V446.836364h-88.436364v-88.715637zM691.665455 60.043636h88.622545v88.622546H691.665455V60.043636zM521.309091 209.082182h88.529454v88.715636h-88.436363v-88.715636z m-170.356364 0h88.529455v88.715636H350.952727v-88.715636zM180.596364 358.120727h88.436363V446.836364h-88.436363v-88.715637z m353.28 546.257455c-93.090909 0-172.404364-13.125818-237.474909-39.098182 48.221091-10.24 103.237818-29.044364 152.66909-63.953455a41.146182 41.146182 0 0 0-47.19709-67.211636c-80.430545 56.692364-184.32 60.602182-218.298182 60.229818a301.614545 301.614545 0 0 1-19.642182-20.666182C92.439273 690.734545 82.850909 586.752 83.502545 533.410909h953.809455c3.537455 0 89.088-0.744727 156.858182-59.857454l5.026909-4.468364c-7.819636 22.993455-155.927273 435.2-665.320727 435.2z m706.746181-464.802909l-25.413818-1.210182-15.266909-20.386909c-0.558545-0.837818-54.644364-74.565818-21.876363-155.461818 20.945455 21.690182 44.125091 55.389091 42.914909 97.093818l-1.675637 58.274909 55.389091-17.966546c0.651636-0.186182 58.833455-17.966545 112.267637-1.582545-18.897455 20.573091-60.043636 45.428364-146.33891 41.239273zM551.284364 606.580364a67.118545 67.118545 0 0 1 0 134.237091 67.118545 67.118545 0 0 1 0-134.237091z m0 82.292363a15.080727 15.080727 0 1 0 0-30.254545 15.080727 15.080727 0 0 0 0 30.254545z" fill="#FFFFFF" /></svg>
|
After Width: | Height: | Size: 2.5 KiB |
1
packages/vscode/src/images/docker.svg
Normal file
1
packages/vscode/src/images/docker.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80"><path fill="#FFF" d="M14.752 32.456l-7.72.002v7.553h7.72v-7.554zm9.65 0h-7.72v7.556h7.72v-7.556zm0-9.445h-7.72v7.556h7.72V23.01zm9.65 9.446h-7.72v7.556h7.72v-7.556zm0-9.445h-7.72v7.556h7.72V23.01zm9.648 9.446h-7.72v7.556h7.72v-7.556zm0-9.445h-7.72v7.556h7.72V23.01zm9.65 9.446l-7.72.002v7.553h7.72v-7.554zm-9.65-18.89h-7.72v7.556h7.72v-7.556zm31.938 23.106c-2.51-1.417-5.85-1.61-8.693-.792-.35-2.958-2.337-5.55-4.7-7.41l-.938-.738-.79.89c-1.58 1.79-2.052 4.768-1.838 7.053.16 1.68.697 3.388 1.756 4.737-.805.473-1.717.85-2.53 1.12-1.657.55-3.456.854-5.206.854H3.544l-.105 1.107c-.354 3.7.165 7.402 1.728 10.778l.673 1.343.078.124c4.622 7.68 12.74 10.914 21.584 10.914 17.125 0 31.248-7.48 37.734-23.284 4.335.222 8.77-1.033 10.89-5.082l.54-1.033-1.028-.578zm-57.77 19.982v.002c-2.18 0-3.955-1.735-3.955-3.866 0-2.132 1.774-3.866 3.954-3.866s3.954 1.732 3.954 3.865c0 2.13-1.77 3.864-3.95 3.864zm-.01-5.854c-1.137 0-2.06.9-2.06 2.013 0 1.11.924 2.01 2.06 2.01 1.134 0 2.057-.9 2.057-2.01 0-1.11-.922-2.013-2.057-2.013z"/></svg>
|
After Width: | Height: | Size: 1.1 KiB |
17
packages/vscode/src/images/logo.svg
Normal file
17
packages/vscode/src/images/logo.svg
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25pt" height="25pt" viewBox="0 0 25 25" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 14.398438 21.09375 C 14.113281 20.417969 13.78125 19.636719 13.496094 18.886719 C 12.792969 17.039062 15.523438 16.753906 15.523438 16.753906 C 15.523438 16.753906 21.378906 16.457031 21.722656 9.683594 C 21.722656 9.683594 19.847656 11.589844 18.210938 11.351562 C 16.574219 11.113281 14.234375 10 12.34375 13.421875 C 10.4375 10 8.109375 11.125 6.472656 11.351562 C 4.835938 11.589844 2.960938 9.683594 2.960938 9.683594 C 3.304688 16.46875 9.160156 16.753906 9.160156 16.753906 C 9.160156 16.753906 11.683594 17.039062 11.1875 18.886719 C 10.992188 19.625 10.757812 20.351562 10.480469 21.0625 L 10.992188 21.996094 L 11.683594 22.535156 L 12.34375 22.714844 L 12.777344 22.714844 L 13.605469 22.097656 L 14.203125 21.289062 Z M 14.398438 21.09375 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 18.167969 11.351562 C 16.53125 11.109375 14.1875 10 12.296875 13.421875 C 12.066406 12.980469 11.777344 12.574219 11.441406 12.207031 C 11.546875 14.699219 11.964844 20.328125 13.453125 22.191406 L 13.542969 22.117188 L 14.140625 21.304688 L 14.351562 21.09375 C 14.066406 20.417969 13.738281 19.636719 13.453125 18.886719 C 12.746094 17.042969 15.480469 16.757812 15.480469 16.757812 C 15.480469 16.757812 21.332031 16.457031 21.679688 9.683594 C 21.679688 9.671875 19.816406 11.578125 18.167969 11.351562 Z M 18.167969 11.351562 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 14.398438 21.519531 C 14.226562 21.519531 14.066406 21.417969 13.996094 21.257812 C 13.707031 20.609375 13.394531 19.835938 13.085938 19.027344 C 12.863281 18.527344 12.894531 17.953125 13.171875 17.480469 C 13.765625 16.507812 15.304688 16.320312 15.480469 16.300781 C 15.710938 16.289062 20.359375 15.980469 21.175781 10.710938 C 20.414062 11.277344 19.257812 11.933594 18.148438 11.769531 C 17.898438 11.738281 17.640625 11.683594 17.367188 11.628906 C 15.8125 11.308594 14.199219 10.976562 12.730469 13.617188 C 12.683594 13.699219 12.609375 13.769531 12.523438 13.808594 C 12.464844 13.835938 12.402344 13.847656 12.339844 13.847656 C 12.179688 13.847656 12.03125 13.757812 11.953125 13.617188 C 10.480469 10.976562 8.871094 11.308594 7.3125 11.628906 C 7.042969 11.683594 6.785156 11.738281 6.53125 11.773438 C 5.421875 11.933594 4.265625 11.277344 3.503906 10.710938 C 4.324219 15.980469 8.972656 16.289062 9.179688 16.300781 C 9.191406 16.300781 9.199219 16.300781 9.207031 16.304688 C 9.269531 16.308594 10.746094 16.488281 11.390625 17.433594 C 11.691406 17.890625 11.773438 18.460938 11.609375 18.984375 C 11.410156 19.738281 11.171875 20.480469 10.890625 21.210938 C 10.800781 21.433594 10.542969 21.546875 10.316406 21.457031 C 10.09375 21.367188 9.980469 21.113281 10.070312 20.886719 C 10.339844 20.191406 10.570312 19.480469 10.761719 18.757812 C 10.855469 18.480469 10.820312 18.175781 10.664062 17.925781 C 10.265625 17.34375 9.207031 17.1875 9.117188 17.175781 C 8.707031 17.148438 2.871094 16.578125 2.519531 9.691406 C 2.507812 9.507812 2.613281 9.339844 2.78125 9.265625 C 2.949219 9.191406 3.144531 9.230469 3.269531 9.359375 C 3.75 9.84375 5.25 11.070312 6.40625 10.898438 C 6.636719 10.867188 6.878906 10.816406 7.136719 10.765625 C 8.628906 10.460938 10.632812 10.046875 12.339844 12.566406 C 14.050781 10.046875 16.054688 10.460938 17.546875 10.765625 C 17.804688 10.816406 18.046875 10.867188 18.269531 10.898438 C 19.4375 11.070312 20.933594 9.847656 21.410156 9.359375 C 21.539062 9.230469 21.734375 9.191406 21.902344 9.265625 C 22.066406 9.339844 22.171875 9.507812 22.164062 9.691406 C 21.8125 16.597656 15.941406 17.148438 15.5625 17.175781 C 15.207031 17.21875 14.230469 17.429688 13.917969 17.941406 C 13.789062 18.183594 13.785156 18.46875 13.90625 18.714844 C 14.210938 19.507812 14.519531 20.265625 14.800781 20.898438 C 14.859375 21.035156 14.847656 21.195312 14.765625 21.316406 C 14.683594 21.441406 14.546875 21.519531 14.398438 21.519531 Z M 14.398438 21.519531 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 0.585938 22.234375 C 0.585938 22.234375 3.0625 21.0625 5.242188 19.804688 C 5.34375 19.742188 6.695312 19.804688 6.695312 19.804688 L 7.882812 19.804688 C 7.988281 19.804688 9.546875 20.75 9.546875 20.75 C 9.546875 20.75 11.171875 21.5 11.453125 21.574219 C 11.738281 21.648438 14.203125 21.304688 14.203125 21.304688 L 16.019531 20.285156 L 17.460938 19.804688 L 20.28125 20.285156 C 20.28125 20.285156 26.648438 21.8125 24.15625 22.683594 C 24.003906 22.730469 22.863281 24.019531 22.730469 24.125 C 22.609375 24.230469 18.960938 25.085938 18.960938 25.085938 L 11.621094 25.085938 L 2.539062 24.382812 Z M 0.585938 22.234375 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 24.324219 22.132812 C 22.722656 22.132812 21.882812 21.59375 21.140625 21.121094 C 20.441406 20.667969 19.78125 20.242188 18.4375 20.242188 C 17.09375 20.242188 16.433594 20.667969 15.734375 21.121094 C 14.992188 21.59375 14.152344 22.132812 12.550781 22.132812 C 10.953125 22.132812 10.113281 21.59375 9.371094 21.121094 C 8.671875 20.667969 8.011719 20.242188 6.667969 20.242188 C 5.324219 20.242188 4.664062 20.667969 3.960938 21.121094 C 3.222656 21.597656 2.382812 22.132812 0.78125 22.132812 C 0.539062 22.132812 0.34375 21.9375 0.34375 21.695312 C 0.34375 21.453125 0.539062 21.253906 0.78125 21.253906 C 2.125 21.253906 2.785156 20.828125 3.488281 20.378906 C 4.226562 19.902344 5.066406 19.363281 6.667969 19.363281 C 8.269531 19.363281 9.105469 19.902344 9.847656 20.378906 C 10.546875 20.828125 11.210938 21.253906 12.550781 21.253906 C 13.894531 21.253906 14.558594 20.828125 15.257812 20.378906 C 15.996094 19.902344 16.835938 19.363281 18.4375 19.363281 C 20.039062 19.363281 20.878906 19.902344 21.617188 20.378906 C 22.320312 20.828125 22.980469 21.253906 24.324219 21.253906 C 24.566406 21.253906 24.761719 21.453125 24.761719 21.695312 C 24.761719 21.9375 24.566406 22.132812 24.324219 22.132812 Z M 24.324219 22.132812 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 9.402344 4.65625 L 8.6875 9.289062 L 13.808594 10.082031 L 14.523438 5.449219 Z M 10.539062 8.199219 L 10.089844 8.136719 L 10.328125 6.367188 L 10.78125 6.425781 Z M 11.621094 8.332031 L 11.171875 8.273438 L 11.410156 6.515625 L 11.859375 6.578125 Z M 12.6875 8.484375 L 12.238281 8.421875 L 12.476562 6.664062 L 12.925781 6.726562 Z M 12.6875 8.484375 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 4.21875 4.515625 L 5.574219 9 L 9.964844 7.675781 L 10.195312 6.386719 L 9.179688 3.019531 Z M 6.773438 7.21875 L 6.339844 7.359375 L 5.792969 5.65625 L 6.226562 5.515625 Z M 7.808594 6.875 L 7.375 7.011719 L 6.832031 5.324219 L 7.265625 5.1875 Z M 8.832031 6.550781 L 8.402344 6.6875 L 7.859375 5 L 8.292969 4.863281 Z M 8.832031 6.550781 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 20.164062 3.867188 L 14.996094 4.234375 L 15.324219 8.90625 L 20.492188 8.542969 Z M 16.484375 7.339844 L 16.394531 5.566406 L 16.847656 5.542969 L 16.9375 7.316406 Z M 17.578125 7.28125 L 17.476562 5.507812 L 17.925781 5.484375 L 18.03125 7.253906 Z M 18.660156 7.222656 L 18.554688 5.449219 L 19.007812 5.421875 L 19.113281 7.195312 Z M 18.660156 7.222656 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 20.613281 0 L 4.503906 0 C 2.019531 0.00390625 0.00390625 2.019531 0 4.503906 L 0 20.613281 C 0.00390625 23.101562 2.019531 25.117188 4.503906 25.117188 L 20.613281 25.117188 C 23.101562 25.117188 25.113281 23.101562 25.117188 20.613281 L 25.117188 4.503906 C 25.113281 2.019531 23.101562 0.00390625 20.613281 0 Z M 24.304688 20.613281 C 24.304688 22.652344 22.652344 24.304688 20.613281 24.304688 L 4.503906 24.304688 C 2.464844 24.304688 0.816406 22.652344 0.8125 20.613281 L 0.8125 4.503906 C 0.816406 2.464844 2.464844 0.816406 4.503906 0.8125 L 20.613281 0.8125 C 22.652344 0.816406 24.304688 2.464844 24.304688 4.503906 Z M 24.304688 20.613281 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 5.445312 4.863281 L 9.242188 4.863281 L 9.242188 7.460938 L 5.445312 7.460938 Z M 5.445312 4.863281 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 9.613281 5.769531 L 13.285156 5.769531 L 13.285156 8.824219 L 9.613281 8.824219 Z M 9.613281 5.769531 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 15.71875 5.027344 L 19.71875 5.027344 L 19.71875 7.75 L 15.71875 7.75 Z M 15.71875 5.027344 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.8 KiB |
1
packages/vscode/src/images/refresh.svg
Normal file
1
packages/vscode/src/images/refresh.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#2D2D30"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#C5C5C5"/></svg>
|
After Width: | Height: | Size: 986 B |
28
packages/vscode/src/provider/base.ts
Normal file
28
packages/vscode/src/provider/base.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import * as vscode from 'vscode'
|
||||
|
||||
export class CteateItemOpt {
|
||||
label: string;
|
||||
context?: ItemContextValue;
|
||||
state?: vscode.TreeItemCollapsibleState = vscode.TreeItemCollapsibleState.None;
|
||||
icon?: string;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
export interface ItemContextValue {
|
||||
type?: string;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export abstract class BaseProvider<T> implements vscode.TreeDataProvider<T> {
|
||||
abstract onDidChangeTreeData?: vscode.Event<T | null | undefined> | undefined;
|
||||
abstract getTreeItem(element: T): vscode.TreeItem | Thenable<vscode.TreeItem>;
|
||||
abstract getChildren(element?: T | undefined): vscode.ProviderResult<T[]>;
|
||||
|
||||
createTreeItem(opts: CteateItemOpt) {
|
||||
let item = new vscode.TreeItem(opts.label, opts.state);
|
||||
item.contextValue = JSON.stringify(opts.context);
|
||||
if (opts.icon) { item.iconPath = `src/images/${opts.icon}.svg` }
|
||||
if (opts.tooltip) { item.tooltip = opts.tooltip; }
|
||||
return item;
|
||||
}
|
||||
}
|
127
packages/vscode/src/provider/docker.ts
Normal file
127
packages/vscode/src/provider/docker.ts
Normal file
@ -0,0 +1,127 @@
|
||||
import * as vscode from 'vscode'
|
||||
import { BaseProvider, ItemContextValue } from './base'
|
||||
import * as docker from '@dayu/docker-api'
|
||||
|
||||
enum Type {
|
||||
ROOT = "ROOT",
|
||||
HOST = "HOST",
|
||||
CONTAINERS = "CONTAINERS",
|
||||
CONTAINER = "CONTAINER",
|
||||
SERVICES = "SERVICES",
|
||||
SERVICE = "SERVICE",
|
||||
NETWORKS = "NETWORKS",
|
||||
NETWORK = "NETWORK",
|
||||
STACKS = "STACKS",
|
||||
STACK = "STACK",
|
||||
NODES = "NODES",
|
||||
NODE = "NODE"
|
||||
}
|
||||
|
||||
let TREE_LIST = [Type.NODES, Type.CONTAINERS, Type.SERVICES, Type.NETWORKS]
|
||||
|
||||
export class DockerProvider extends BaseProvider<vscode.TreeItem> {
|
||||
onDidChangeTreeData?: vscode.Event<vscode.TreeItem | null | undefined> | undefined;
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
super();
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dayu.container.logs', (item: vscode.TreeItem) => {
|
||||
let value: ItemContextValue = JSON.parse(item.contextValue);
|
||||
let url = `https://faas.n.yumc.pw?action=container&data=${value.data.id}`;
|
||||
return vscode.commands.executeCommand("mini-browser.openUrl", url);
|
||||
}),
|
||||
vscode.window.registerTreeDataProvider('docker-explorer', this)
|
||||
)
|
||||
}
|
||||
|
||||
getTreeItem(element: vscode.TreeItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
|
||||
return element;
|
||||
}
|
||||
|
||||
async getChildren(element?: vscode.TreeItem | undefined): Promise<vscode.TreeItem[]> {
|
||||
if (!element || !element.contextValue) {
|
||||
return [this.createTreeItem({
|
||||
label: 'Docker',
|
||||
context: {
|
||||
type: Type.ROOT
|
||||
},
|
||||
state: vscode.TreeItemCollapsibleState.Collapsed,
|
||||
icon: "docker"
|
||||
})]
|
||||
}
|
||||
let value: ItemContextValue = JSON.parse(element.contextValue);
|
||||
switch (value.type) {
|
||||
case Type.ROOT:
|
||||
return TREE_LIST.map(i => {
|
||||
return this.createTreeItem({
|
||||
label: i,
|
||||
context: {
|
||||
type: i
|
||||
},
|
||||
state: vscode.TreeItemCollapsibleState.Collapsed
|
||||
})
|
||||
})
|
||||
case Type.NODES:
|
||||
let nodes = await docker.node.list();
|
||||
return nodes.map(n => {
|
||||
return this.createTreeItem({
|
||||
label: n.ID,
|
||||
context: {
|
||||
type: Type.NODE,
|
||||
data: {
|
||||
id: n.ID
|
||||
}
|
||||
},
|
||||
tooltip: JSON.stringify(n, undefined, 2)
|
||||
})
|
||||
})
|
||||
case Type.CONTAINERS:
|
||||
let containers = await docker.container.list();
|
||||
return containers.map(c => {
|
||||
return this.createTreeItem({
|
||||
label: c.Names[0],
|
||||
context: {
|
||||
type: Type.CONTAINER,
|
||||
data: {
|
||||
id: c.Id
|
||||
}
|
||||
},
|
||||
tooltip: JSON.stringify(c, undefined, 2)
|
||||
})
|
||||
})
|
||||
case Type.SERVICES:
|
||||
let services = await docker.service.list();
|
||||
return services.map(s => {
|
||||
return this.createTreeItem({
|
||||
label: s.Spec.Name,
|
||||
context: {
|
||||
type: Type.SERVICE,
|
||||
data: {
|
||||
id: s.ID
|
||||
}
|
||||
},
|
||||
tooltip: JSON.stringify(s, undefined, 2)
|
||||
})
|
||||
})
|
||||
case Type.NETWORKS:
|
||||
let networks = await docker.network.list();
|
||||
return networks.map(n => {
|
||||
return this.createTreeItem({
|
||||
label: n.Name,
|
||||
context: {
|
||||
type: Type.NETWORK,
|
||||
data: {
|
||||
id: n.Id
|
||||
}
|
||||
},
|
||||
tooltip: JSON.stringify(n, undefined, 2)
|
||||
})
|
||||
})
|
||||
case Type.CONTAINER:
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
48
packages/vscode/src/provider/faas.ts
Normal file
48
packages/vscode/src/provider/faas.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import * as vscode from 'vscode'
|
||||
import * as faas from '@dayu/faas'
|
||||
import { BaseProvider, ItemContextValue } from './base'
|
||||
|
||||
enum Type {
|
||||
ROOT = "ROOT",
|
||||
}
|
||||
|
||||
export class OpenFaasProvider extends BaseProvider<vscode.TreeItem> {
|
||||
onDidChangeTreeData?: vscode.Event<vscode.TreeItem>;
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
super()
|
||||
context.subscriptions.push(
|
||||
vscode.window.registerTreeDataProvider('openfaas-explorer', this)
|
||||
)
|
||||
}
|
||||
|
||||
getTreeItem(element: vscode.TreeItem): vscode.TreeItem | Promise<vscode.TreeItem> {
|
||||
return element;
|
||||
}
|
||||
|
||||
async getChildren(element?: vscode.TreeItem): Promise<vscode.TreeItem[]> {
|
||||
if (!element || !element.contextValue) {
|
||||
return [this.createTreeItem({
|
||||
label: "OpenFaaS",
|
||||
state: vscode.TreeItemCollapsibleState.Collapsed,
|
||||
context: {
|
||||
type: Type.ROOT
|
||||
},
|
||||
icon: "logo"
|
||||
})]
|
||||
}
|
||||
let value: ItemContextValue = JSON.parse(element.contextValue);
|
||||
switch (value.type) {
|
||||
case Type.ROOT:
|
||||
let funcs = await faas.getFunctions();
|
||||
return funcs.map(f => {
|
||||
return this.createTreeItem({
|
||||
label: f.name,
|
||||
tooltip: JSON.stringify(f, undefined, 2)
|
||||
})
|
||||
});
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
2
packages/vscode/src/provider/index.ts
Normal file
2
packages/vscode/src/provider/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './faas'
|
||||
export * from './docker'
|
22
packages/vscode/src/test/extension.test.ts
Normal file
22
packages/vscode/src/test/extension.test.ts
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// Note: This example test is leveraging the Mocha test framework.
|
||||
// Please refer to their documentation on https://mochajs.org/ for help.
|
||||
//
|
||||
|
||||
// The module 'assert' provides assertion methods from node
|
||||
import * as assert from 'assert';
|
||||
|
||||
// You can import and use all API from the 'vscode' module
|
||||
// as well as import your extension to test it
|
||||
// import * as vscode from 'vscode';
|
||||
// import * as myExtension from '../extension';
|
||||
|
||||
// Defines a Mocha test suite to group tests of similar kind together
|
||||
suite("Extension Tests", function () {
|
||||
|
||||
// Defines a Mocha unit test
|
||||
test("Something 1", function() {
|
||||
assert.equal(-1, [1, 2, 3].indexOf(5));
|
||||
assert.equal(-1, [1, 2, 3].indexOf(0));
|
||||
});
|
||||
});
|
23
packages/vscode/src/test/index.ts
Normal file
23
packages/vscode/src/test/index.ts
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
|
||||
//
|
||||
// This file is providing the test runner to use when running extension tests.
|
||||
// By default the test runner in use is Mocha based.
|
||||
//
|
||||
// You can provide your own test runner if you want to override it by exporting
|
||||
// a function run(testsRoot: string, clb: (error: Error, failures?: number) => void): void
|
||||
// that the extension host can call to run the tests. The test runner is expected to use console.log
|
||||
// to report the results back to the caller. When the tests are finished, return
|
||||
// a possible error to the callback or null if none.
|
||||
|
||||
import * as testRunner from 'vscode/lib/testrunner';
|
||||
|
||||
// You can directly control Mocha options by configuring the test runner below
|
||||
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options
|
||||
// for more info
|
||||
testRunner.configure({
|
||||
ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
|
||||
useColors: true // colored output from test results
|
||||
});
|
||||
|
||||
module.exports = testRunner;
|
7
packages/vscode/tsconfig.json
Normal file
7
packages/vscode/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"outDir": "dist"
|
||||
}
|
||||
}
|
41
packages/vscode/vsc-extension-quickstart.md
Normal file
41
packages/vscode/vsc-extension-quickstart.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Welcome to your VS Code Extension
|
||||
|
||||
## What's in the folder
|
||||
|
||||
* This folder contains all of the files necessary for your extension.
|
||||
* `package.json` - this is the manifest file in which you declare your extension and command.
|
||||
* The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin.
|
||||
* `src/extension.ts` - this is the main file where you will provide the implementation of your command.
|
||||
* The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`.
|
||||
* We pass the function containing the implementation of the command as the second parameter to `registerCommand`.
|
||||
|
||||
## Get up and running straight away
|
||||
|
||||
* Press `F5` to open a new window with your extension loaded.
|
||||
* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`.
|
||||
* Set breakpoints in your code inside `src/extension.ts` to debug your extension.
|
||||
* Find output from your extension in the debug console.
|
||||
|
||||
## Make changes
|
||||
|
||||
* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`.
|
||||
* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes.
|
||||
|
||||
## Explore the API
|
||||
|
||||
* You can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts`.
|
||||
|
||||
## Run tests
|
||||
|
||||
* Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`.
|
||||
* Press `F5` to run the tests in a new window with your extension loaded.
|
||||
* See the output of the test result in the debug console.
|
||||
* Make changes to `test/extension.test.ts` or create new test files inside the `test` folder.
|
||||
* By convention, the test runner will only consider files matching the name pattern `**.test.ts`.
|
||||
* You can create folders inside the `test` folder to structure your tests any way you want.
|
||||
|
||||
## Go further
|
||||
|
||||
* Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/testing-extension).
|
||||
* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace.
|
||||
* Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"outDir": "dist",
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"noImplicitAny": true,
|
||||
"allowUnreachableCode": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true
|
||||
}
|
||||
}
|
15
tslint.json
Normal file
15
tslint.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-string-throw": true,
|
||||
"no-unused-expression": true,
|
||||
"no-duplicate-variable": true,
|
||||
"curly": true,
|
||||
"class-name": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": true
|
||||
},
|
||||
"defaultSeverity": "warning"
|
||||
}
|
Loading…
Reference in New Issue
Block a user