feat: add task and dashboard controller
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		@@ -11,7 +11,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "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",
 | 
			
		||||
        "debug": "npx nodemon dist/index.js",
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
@@ -29,5 +29,18 @@
 | 
			
		||||
        "rimraf": "^2.6.3",
 | 
			
		||||
        "ts-node-dev": "^1.0.0-pre.40",
 | 
			
		||||
        "typescript": "^3.5.2"
 | 
			
		||||
    },
 | 
			
		||||
    "nodemonConfig": {
 | 
			
		||||
        "verbose": true,
 | 
			
		||||
        "ignore": [
 | 
			
		||||
            ".git",
 | 
			
		||||
            "public"
 | 
			
		||||
        ],
 | 
			
		||||
        "watch": [
 | 
			
		||||
            "./",
 | 
			
		||||
            "../../node_modules"
 | 
			
		||||
        ],
 | 
			
		||||
        "delay": "1500",
 | 
			
		||||
        "ext": "js,json"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -34,10 +34,10 @@ socket.on('connect', () => {
 | 
			
		||||
            case "container":
 | 
			
		||||
                socket.emit('logs', {
 | 
			
		||||
                    id: query.data,
 | 
			
		||||
                    since: Date.now() / 1000 - 60 * 15,
 | 
			
		||||
                    until: Date.now() / 1000,
 | 
			
		||||
                    stderr: false,
 | 
			
		||||
                    tail: "all"
 | 
			
		||||
                    // since: Date.now() / 1000 - 60 * 15,
 | 
			
		||||
                    // until: Date.now() / 1000,
 | 
			
		||||
                    // stderr: false,
 | 
			
		||||
                    tail: "200"
 | 
			
		||||
                })
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								packages/core/src/controller/dashboard.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								packages/core/src/controller/dashboard.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
import * as docker from '@dayu/docker-api'
 | 
			
		||||
import { controller, httpGet } from "@cc-server/binding";
 | 
			
		||||
 | 
			
		||||
const STACK_LABEL = 'com.docker.stack.namespace';
 | 
			
		||||
 | 
			
		||||
@controller('/dashboard')
 | 
			
		||||
class DashboardController {
 | 
			
		||||
    @httpGet('')
 | 
			
		||||
    async index() {
 | 
			
		||||
        let stacks = [];
 | 
			
		||||
        let services = [];
 | 
			
		||||
        let svrs = await docker.service.list();
 | 
			
		||||
        for (const service of svrs) {
 | 
			
		||||
            if (service.Spec.Labels[STACK_LABEL]) {
 | 
			
		||||
                stacks.push(service.Spec.Labels[STACK_LABEL]);
 | 
			
		||||
            }
 | 
			
		||||
            services.push(service.Spec.Name)
 | 
			
		||||
        }
 | 
			
		||||
        let networks = await docker.network.list();
 | 
			
		||||
        let nodes = await docker.node.list();
 | 
			
		||||
        let tasks = await docker.task.list();
 | 
			
		||||
        return {
 | 
			
		||||
            nodes: nodes.map(n => n.Description.Hostname),
 | 
			
		||||
            tasks: tasks.map(t => t.ID),
 | 
			
		||||
            stacks: Array.from(new Set(stacks)),
 | 
			
		||||
            services,
 | 
			
		||||
            networks: networks.map(n => n.Name)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
export * from './node'
 | 
			
		||||
export * from './task'
 | 
			
		||||
export * from './swarm'
 | 
			
		||||
export * from './system'
 | 
			
		||||
export * from './network'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										178
									
								
								packages/docker-api/src/api/types/task.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								packages/docker-api/src/api/types/task.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,178 @@
 | 
			
		||||
import { Options, Labels } from '../common'
 | 
			
		||||
 | 
			
		||||
export namespace task {
 | 
			
		||||
 | 
			
		||||
    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 ContainerSpec {
 | 
			
		||||
        Image: string;
 | 
			
		||||
        Labels: Labels;
 | 
			
		||||
        Privileges: Privileges;
 | 
			
		||||
        Mounts: Mount[];
 | 
			
		||||
        Isolation: string;
 | 
			
		||||
        Env: string[];
 | 
			
		||||
        User: string;
 | 
			
		||||
        Args: string[];
 | 
			
		||||
        Secrets: Secret[];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
        MaxAttempts: number;
 | 
			
		||||
        Delay?: number;
 | 
			
		||||
        Window?: number;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    export interface LogDriver {
 | 
			
		||||
        Name: string;
 | 
			
		||||
        Options: Options;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface Spec {
 | 
			
		||||
        ContainerSpec: ContainerSpec;
 | 
			
		||||
        Resources: Resources;
 | 
			
		||||
        Placement: Placement;
 | 
			
		||||
        Networks: Network[];
 | 
			
		||||
        ForceUpdate: number;
 | 
			
		||||
        RestartPolicy: RestartPolicy;
 | 
			
		||||
        LogDriver: LogDriver;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface ContainerStatus {
 | 
			
		||||
        ContainerID: string;
 | 
			
		||||
        PID: number;
 | 
			
		||||
        ExitCode: number;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface Port {
 | 
			
		||||
        Protocol: string;
 | 
			
		||||
        TargetPort: number;
 | 
			
		||||
        PublishedPort: number;
 | 
			
		||||
        PublishMode: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface PortStatus {
 | 
			
		||||
        Ports: Port[];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface Status {
 | 
			
		||||
        Timestamp: string;
 | 
			
		||||
        State: string;
 | 
			
		||||
        Message: string;
 | 
			
		||||
        Err: string;
 | 
			
		||||
        ContainerStatus: ContainerStatus;
 | 
			
		||||
        PortStatus: PortStatus;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface DriverConfiguration {
 | 
			
		||||
        Name: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface Driver {
 | 
			
		||||
        Name: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface Config {
 | 
			
		||||
        Subnet: string;
 | 
			
		||||
        Gateway: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface IPAMOptions {
 | 
			
		||||
        Driver: Driver;
 | 
			
		||||
        Configs: Config[];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface DriverState {
 | 
			
		||||
        Name: string;
 | 
			
		||||
        Options: Options;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface NetworksAttachment {
 | 
			
		||||
        Network: Network;
 | 
			
		||||
        Addresses: string[];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface Task {
 | 
			
		||||
        ID: string;
 | 
			
		||||
        Version: Version;
 | 
			
		||||
        CreatedAt: string;
 | 
			
		||||
        UpdatedAt: any;
 | 
			
		||||
        Labels: Labels;
 | 
			
		||||
        Spec: Spec;
 | 
			
		||||
        ServiceID: string;
 | 
			
		||||
        Slot: number;
 | 
			
		||||
        NodeID: string;
 | 
			
		||||
        Status: Status;
 | 
			
		||||
        DesiredState: string;
 | 
			
		||||
        NetworksAttachments: NetworksAttachment[];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
export * from './node'
 | 
			
		||||
export * from './task'
 | 
			
		||||
export * from './swarm'
 | 
			
		||||
export * from './system'
 | 
			
		||||
export * from './network'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								packages/docker-api/src/client/task.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/docker-api/src/client/task.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
import * as api from '../utils/api'
 | 
			
		||||
import * as types from '../api/types'
 | 
			
		||||
 | 
			
		||||
export namespace task {
 | 
			
		||||
    export async function list() {
 | 
			
		||||
        return await api.get<types.task.Task[]>('/tasks');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -17,7 +17,8 @@ enum Type {
 | 
			
		||||
    NODE = "NODE"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let TREE_LIST = [Type.NODES, Type.CONTAINERS, Type.SERVICES, Type.NETWORKS]
 | 
			
		||||
let TREE_LIST = [Type.NODES, Type.CONTAINERS, Type.SERVICES, Type.STACKS, Type.NETWORKS]
 | 
			
		||||
const STACK_LABEL = 'com.docker.stack.namespace';
 | 
			
		||||
 | 
			
		||||
export class DockerProvider extends BaseProvider<vscode.TreeItem> {
 | 
			
		||||
    onDidChangeTreeData?: vscode.Event<vscode.TreeItem | null | undefined> | undefined;
 | 
			
		||||
@@ -117,9 +118,37 @@ export class DockerProvider extends BaseProvider<vscode.TreeItem> {
 | 
			
		||||
                        tooltip: JSON.stringify(n, undefined, 2)
 | 
			
		||||
                    })
 | 
			
		||||
                })
 | 
			
		||||
            case Type.CONTAINER:
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            case Type.STACKS:
 | 
			
		||||
                let stacks: { [key: string]: string[] } = {};
 | 
			
		||||
                let svrs = await docker.service.list();
 | 
			
		||||
                for (const service of svrs) {
 | 
			
		||||
                    let stackName = service.Spec.Labels[STACK_LABEL]
 | 
			
		||||
                    if (stackName) {
 | 
			
		||||
                        let stack = stacks[stackName] || [];
 | 
			
		||||
                        stack.push(service.Spec.Name);
 | 
			
		||||
                        stacks[stackName] = stack;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return Object.keys(stacks).map(stack => {
 | 
			
		||||
                    return this.createTreeItem({
 | 
			
		||||
                        label: stack,
 | 
			
		||||
                        context: {
 | 
			
		||||
                            type: Type.STACK,
 | 
			
		||||
                            data: {
 | 
			
		||||
                                name: stack,
 | 
			
		||||
                                list: stacks[stack]
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        state: vscode.TreeItemCollapsibleState.Collapsed
 | 
			
		||||
                    })
 | 
			
		||||
                })
 | 
			
		||||
            case Type.STACK:
 | 
			
		||||
                let list: string[] = value.data.list;
 | 
			
		||||
                return list.map(s => {
 | 
			
		||||
                    return this.createTreeItem({
 | 
			
		||||
                        label: s
 | 
			
		||||
                    })
 | 
			
		||||
                })
 | 
			
		||||
            default:
 | 
			
		||||
        }
 | 
			
		||||
        return [];
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user