feat(.gitea/workflows): Add GitHub Actions workflows for Docker build and test
This commit is contained in:
parent
bec47150a3
commit
9de86bd382
71
.gitea/workflows/docker_nottags.yaml
Normal file
71
.gitea/workflows/docker_nottags.yaml
Normal file
@ -0,0 +1,71 @@
|
||||
name: Docker (tags)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
IMAGE: code.foss.global/hosttoday/ht-docker-node:npmci
|
||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
|
||||
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||
NPMCI_LOGIN_DOCKER_GITEA: ${{ github.server_url }}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }}
|
||||
NPMCI_LOGIN_DOCKER_DOCKERREGISTRY: ${{ secrets.NPMCI_LOGIN_DOCKER_DOCKERREGISTRY }}
|
||||
|
||||
jobs:
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install pnpm and npmci
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Audit production dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --prod
|
||||
continue-on-error: true
|
||||
|
||||
- name: Audit development dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --dev
|
||||
continue-on-error: true
|
||||
|
||||
test:
|
||||
needs: security
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Test stable
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci npm test
|
||||
|
||||
- name: Test build
|
||||
run: |
|
||||
npmci npm prepare
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci command npm run build
|
106
.gitea/workflows/docker_tags.yaml
Normal file
106
.gitea/workflows/docker_tags.yaml
Normal file
@ -0,0 +1,106 @@
|
||||
name: Docker (tags)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
IMAGE: code.foss.global/hosttoday/ht-docker-node:npmci
|
||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
|
||||
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||
NPMCI_LOGIN_DOCKER_GITEA: ${{ github.server_url }}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }}
|
||||
NPMCI_LOGIN_DOCKER_DOCKERREGISTRY: ${{ secrets.NPMCI_LOGIN_DOCKER_DOCKERREGISTRY }}
|
||||
|
||||
jobs:
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Audit production dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --prod
|
||||
continue-on-error: true
|
||||
|
||||
- name: Audit development dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --dev
|
||||
continue-on-error: true
|
||||
|
||||
test:
|
||||
needs: security
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Test stable
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci npm test
|
||||
|
||||
- name: Test build
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci command npm run build
|
||||
|
||||
release:
|
||||
needs: test
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: code.foss.global/hosttoday/ht-docker-dbase:npmci
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
|
||||
- name: Release
|
||||
run: |
|
||||
npmci docker login
|
||||
npmci docker build
|
||||
npmci docker test
|
||||
# npmci docker push
|
||||
npmci docker push
|
||||
|
||||
metadata:
|
||||
needs: test
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Trigger
|
||||
run: npmci trigger
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,7 +3,6 @@
|
||||
# artifacts
|
||||
coverage/
|
||||
public/
|
||||
pages/
|
||||
|
||||
# installs
|
||||
node_modules/
|
||||
@ -17,4 +16,4 @@ node_modules/
|
||||
dist/
|
||||
dist_*/
|
||||
|
||||
# custom
|
||||
#------# custom
|
@ -24,7 +24,7 @@ RUN rm -rf node_modules/ && pnpm install --prod
|
||||
|
||||
|
||||
## STAGE 3 // rebuild dependencies for alpine
|
||||
FROM code.foss.global/host.today/ht-docker-node:alpine_npmci as node3
|
||||
FROM code.foss.global/host.today/ht-docker-node:alpinenpmci as node3
|
||||
WORKDIR /app
|
||||
COPY --from=node2 /app /app
|
||||
ARG NPMCI_TOKEN_NPM2
|
||||
|
@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## 2024-12-29 - 1.1.0 - feat(.gitea/workflows)
|
||||
Add GitHub Actions workflows for Docker build and test
|
||||
|
||||
- Added .gitea/workflows/docker_nottags.yaml for handling Docker builds on non-tagged commits.
|
||||
- Added .gitea/workflows/docker_tags.yaml for handling Docker builds on tagged commits.
|
||||
- Both workflows include steps for security audits, testing, and build preparation.
|
||||
|
||||
## 2024-12-29 - 1.0.135 - fix(core)
|
||||
Fix image retrieval and service deployment process for workload services
|
||||
|
||||
|
@ -13,12 +13,12 @@
|
||||
"gitzone": {
|
||||
"projectType": "service",
|
||||
"module": {
|
||||
"githost": "gitlab.com",
|
||||
"gitscope": "losslessone/services/servezone",
|
||||
"githost": "code.foss.global",
|
||||
"gitscope": "serve.zone",
|
||||
"gitrepo": "coreflow",
|
||||
"description": "A comprehensive tool for managing Docker-based applications and services, enabling efficient scaling, network management, and integration with cloud services.",
|
||||
"npmPackagename": "@serve.zone/coreflow",
|
||||
"license": "UNLICENSED",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"Docker",
|
||||
"Service scaling",
|
||||
|
@ -18,7 +18,7 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://gitlab.com/pushrocks/coreflow.git"
|
||||
"url": "https://code.foss.global/serve.zone/coreflow.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Docker",
|
||||
@ -49,9 +49,9 @@
|
||||
"author": "Lossless GmbH",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://gitlab.com/pushrocks/coreflow/issues"
|
||||
"url": "https://gitlab.com/losslessone/services/servezone/coreflow/issues"
|
||||
},
|
||||
"homepage": "https://gitlab.com/pushrocks/coreflow#readme",
|
||||
"homepage": "https://gitlab.com/losslessone/services/servezone/coreflow#readme",
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^2.2.0",
|
||||
"@git.zone/tsrun": "^1.3.3",
|
||||
@ -100,4 +100,4 @@
|
||||
"browserslist": [
|
||||
"last 1 chrome versions"
|
||||
]
|
||||
}
|
||||
}
|
74
readme.md
74
readme.md
@ -1,4 +1,5 @@
|
||||
# @serve.zone/coreflow
|
||||
|
||||
A comprehensive solution for managing Docker and scaling applications across servers, handling tasks from service provisioning to network traffic management.
|
||||
|
||||
## Install
|
||||
@ -42,6 +43,7 @@ await coreflowInstance.stop();
|
||||
```
|
||||
|
||||
In the above example:
|
||||
|
||||
- The Coreflow instance is initialized.
|
||||
- Coreflow is started, which internally initializes various managers and connectors.
|
||||
- The method `handleDockerEvents` is used to handle Docker events.
|
||||
@ -54,8 +56,8 @@ Coreflow manages applications and services, often requiring direct interactions
|
||||
```typescript
|
||||
// Assuming coreflowInstance is already started as per previous examples
|
||||
const serviceConnection = coreflowInstance.createServiceConnection({
|
||||
serviceName: "myDatabaseService",
|
||||
servicePort: 3306
|
||||
serviceName: 'myDatabaseService',
|
||||
servicePort: 3306,
|
||||
});
|
||||
|
||||
serviceConnection.connect().then(() => {
|
||||
@ -69,7 +71,7 @@ Coreflow excels in scaling applications across multiple servers. This involves n
|
||||
|
||||
```typescript
|
||||
const scalingPolicy = {
|
||||
serviceName: "apiService",
|
||||
serviceName: 'apiService',
|
||||
replicaCount: 5, // Target number of replicas
|
||||
maxReplicaCount: 10, // Maximum number of replicas
|
||||
minReplicaCount: 2, // Minimum number of replicas
|
||||
@ -81,6 +83,7 @@ coreflowInstance.applyScalingPolicy(scalingPolicy).then(() => {
|
||||
```
|
||||
|
||||
In the above example:
|
||||
|
||||
- A scaling policy is defined with target, maximum, and minimum replica counts for the `apiService`.
|
||||
- The `applyScalingPolicy` method of the Coreflow instance is used to apply this scaling policy.
|
||||
|
||||
@ -92,10 +95,10 @@ One of Coreflow's key features is its ability to manage network traffic, ensurin
|
||||
import { TrafficRule } from '@serve.zone/coreflow';
|
||||
|
||||
const rule: TrafficRule = {
|
||||
serviceName: "webService",
|
||||
serviceName: 'webService',
|
||||
externalPort: 80,
|
||||
internalPort: 3000,
|
||||
protocol: "http",
|
||||
protocol: 'http',
|
||||
};
|
||||
|
||||
coreflowInstance.applyTrafficRule(rule).then(() => {
|
||||
@ -104,6 +107,7 @@ coreflowInstance.applyTrafficRule(rule).then(() => {
|
||||
```
|
||||
|
||||
In the above example:
|
||||
|
||||
- A traffic rule is defined for the `webService`, redirecting external traffic from port 80 to the service's internal port 3000.
|
||||
- The `applyTrafficRule` method is used to enforce this rule.
|
||||
|
||||
@ -113,9 +117,9 @@ Coreflow integrates continuous integration and deployment processes, allowing se
|
||||
|
||||
```typescript
|
||||
const deploymentConfig = {
|
||||
serviceName: "userAuthService",
|
||||
image: "myregistry.com/userauthservice:latest",
|
||||
updatePolicy: "rolling" // or "recreate"
|
||||
serviceName: 'userAuthService',
|
||||
image: 'myregistry.com/userauthservice:latest',
|
||||
updatePolicy: 'rolling', // or "recreate"
|
||||
};
|
||||
|
||||
coreflowInstance.deployService(deploymentConfig).then(() => {
|
||||
@ -124,6 +128,7 @@ coreflowInstance.deployService(deploymentConfig).then(() => {
|
||||
```
|
||||
|
||||
In the above example:
|
||||
|
||||
- A deployment configuration is created for the `userAuthService` using the latest image from the specified registry.
|
||||
- The `deployService` method is then used to deploy the service using the specified update policy (e.g., rolling updates or recreating the service).
|
||||
|
||||
@ -132,12 +137,13 @@ In the above example:
|
||||
To keep track of your applications' health and performance, Coreflow provides tools for logging, monitoring, and alerting.
|
||||
|
||||
```typescript
|
||||
coreflowInstance.monitorService("webService").on('serviceHealthUpdate', (healthStatus) => {
|
||||
coreflowInstance.monitorService('webService').on('serviceHealthUpdate', (healthStatus) => {
|
||||
console.log(`Received health update for webService: ${healthStatus}`);
|
||||
});
|
||||
```
|
||||
|
||||
In the above example:
|
||||
|
||||
- The `monitorService` method is used to monitor the health status of the `webService`.
|
||||
- When a health update event is received, it is logged to the console.
|
||||
|
||||
@ -175,8 +181,8 @@ coreflowInstance.handleDockerEvents().then(() => {
|
||||
|
||||
```typescript
|
||||
const serviceConnection = coreflowInstance.createServiceConnection({
|
||||
serviceName: "databaseService",
|
||||
servicePort: 5432
|
||||
serviceName: 'databaseService',
|
||||
servicePort: 5432,
|
||||
});
|
||||
|
||||
serviceConnection.connect().then(() => {
|
||||
@ -188,7 +194,7 @@ serviceConnection.connect().then(() => {
|
||||
|
||||
```typescript
|
||||
const scalingPolicy = {
|
||||
serviceName: "microserviceA",
|
||||
serviceName: 'microserviceA',
|
||||
replicaCount: 3, // Starting with 3 replicas
|
||||
maxReplicaCount: 10, // Allowing up to 10 replicas
|
||||
minReplicaCount: 2, // Ensuring at least 2 replicas
|
||||
@ -206,17 +212,17 @@ import { TrafficRule } from '@serve.zone/coreflow';
|
||||
|
||||
const trafficRules: TrafficRule[] = [
|
||||
{
|
||||
serviceName: "frontendService",
|
||||
serviceName: 'frontendService',
|
||||
externalPort: 80,
|
||||
internalPort: 3000,
|
||||
protocol: "http",
|
||||
protocol: 'http',
|
||||
},
|
||||
{
|
||||
serviceName: "apiService",
|
||||
serviceName: 'apiService',
|
||||
externalPort: 443,
|
||||
internalPort: 4000,
|
||||
protocol: "https",
|
||||
}
|
||||
protocol: 'https',
|
||||
},
|
||||
];
|
||||
|
||||
Promise.all(trafficRules.map((rule) => coreflowInstance.applyTrafficRule(rule))).then(() => {
|
||||
@ -228,9 +234,9 @@ Promise.all(trafficRules.map((rule) => coreflowInstance.applyTrafficRule(rule)))
|
||||
|
||||
```typescript
|
||||
const deploymentConfig = {
|
||||
serviceName: "authService",
|
||||
image: "myregistry.com/authservice:latest",
|
||||
updatePolicy: "rolling", // Performing rolling updates
|
||||
serviceName: 'authService',
|
||||
image: 'myregistry.com/authservice:latest',
|
||||
updatePolicy: 'rolling', // Performing rolling updates
|
||||
};
|
||||
|
||||
coreflowInstance.deployService(deploymentConfig).then(() => {
|
||||
@ -241,7 +247,7 @@ coreflowInstance.deployService(deploymentConfig).then(() => {
|
||||
#### Step 7: Monitoring a Service
|
||||
|
||||
```typescript
|
||||
coreflowInstance.monitorService("frontendService").on('serviceHealthUpdate', (healthStatus) => {
|
||||
coreflowInstance.monitorService('frontendService').on('serviceHealthUpdate', (healthStatus) => {
|
||||
console.log(`Health update for frontendService: ${healthStatus}`);
|
||||
});
|
||||
```
|
||||
@ -262,7 +268,7 @@ const checkinTask = new Task({
|
||||
buffered: true,
|
||||
taskFunction: async () => {
|
||||
console.log('Running checkin task...');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const taskManager = coreflowInstance.taskManager;
|
||||
@ -284,18 +290,18 @@ const coretrafficConnector = new CoretrafficConnector(coreflowInstance);
|
||||
|
||||
const reverseProxyConfigs = [
|
||||
{
|
||||
hostName: "example.com",
|
||||
destinationIp: "192.168.1.100",
|
||||
destinationPort: "3000",
|
||||
privateKey: "<your-private-key>",
|
||||
publicKey: "<your-public-key>",
|
||||
hostName: 'example.com',
|
||||
destinationIp: '192.168.1.100',
|
||||
destinationPort: '3000',
|
||||
privateKey: '<your-private-key>',
|
||||
publicKey: '<your-public-key>',
|
||||
},
|
||||
{
|
||||
hostName: "api.example.com",
|
||||
destinationIp: "192.168.1.101",
|
||||
destinationPort: "4000",
|
||||
privateKey: "<your-private-key>",
|
||||
publicKey: "<your-public-key>",
|
||||
hostName: 'api.example.com',
|
||||
destinationIp: '192.168.1.101',
|
||||
destinationPort: '4000',
|
||||
privateKey: '<your-private-key>',
|
||||
publicKey: '<your-public-key>',
|
||||
},
|
||||
];
|
||||
|
||||
@ -323,7 +329,7 @@ cloudlyConnector.start().then(() => {
|
||||
```typescript
|
||||
cloudlyConnector.getConfigFromCloudly().then((config) => {
|
||||
console.log('Received configuration from Cloudly:', config);
|
||||
|
||||
|
||||
coreflowInstance.clusterManager.provisionWorkloadServices(config).then(() => {
|
||||
console.log('Workload services provisioned based on Cloudly config.');
|
||||
});
|
||||
@ -335,4 +341,4 @@ cloudlyConnector.getConfigFromCloudly().then((config) => {
|
||||
Coreflow is a powerful and flexible tool for managing Docker-based applications, scaling services, configuring network traffic, handling continuous deployments, and ensuring observability of your infrastructure. The examples provided aim to give a comprehensive understanding of how to use Coreflow in various scenarios, ensuring it meets your DevOps and CI/CD needs.
|
||||
|
||||
By leveraging Coreflow's rich feature set, you can optimize your infrastructure for high availability, scalability, and efficient operation across multiple servers and environments.
|
||||
undefined
|
||||
undefined
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/coreflow',
|
||||
version: '1.0.135',
|
||||
version: '1.1.0',
|
||||
description: 'A comprehensive tool for managing Docker-based applications and services, enabling efficient scaling, network management, and integration with cloud services.'
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ export class ClusterManager {
|
||||
this.coreflowRef.cloudlyConnector.cloudlyApiClient.configUpdateSubject.subscribe(
|
||||
async (dataArg) => {
|
||||
this.coreflowRef.taskManager.updateBaseServicesTask.trigger();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -60,14 +60,17 @@ export class ClusterManager {
|
||||
// make sure there is a network for the webgateway
|
||||
let sznWebgatewayNetwork = await plugins.docker.DockerNetwork.getNetworkByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
this.commonDockerData.networkNames.sznWebgateway
|
||||
this.commonDockerData.networkNames.sznWebgateway,
|
||||
);
|
||||
|
||||
if (!sznWebgatewayNetwork) {
|
||||
logger.log('info', 'Creating network: ' + this.commonDockerData.networkNames.sznWebgateway);
|
||||
sznWebgatewayNetwork = await plugins.docker.DockerNetwork.createNetwork(this.coreflowRef.dockerHost, {
|
||||
Name: this.commonDockerData.networkNames.sznWebgateway,
|
||||
});
|
||||
sznWebgatewayNetwork = await plugins.docker.DockerNetwork.createNetwork(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
Name: this.commonDockerData.networkNames.sznWebgateway,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
logger.log('ok', 'sznWebgateway is already present');
|
||||
}
|
||||
@ -75,12 +78,15 @@ export class ClusterManager {
|
||||
// corechat network so base services can talk to each other
|
||||
let sznCorechatNetwork = await plugins.docker.DockerNetwork.getNetworkByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
this.commonDockerData.networkNames.sznCorechat
|
||||
this.commonDockerData.networkNames.sznCorechat,
|
||||
);
|
||||
if (!sznCorechatNetwork) {
|
||||
sznCorechatNetwork = await plugins.docker.DockerNetwork.createNetwork(this.coreflowRef.dockerHost, {
|
||||
Name: this.commonDockerData.networkNames.sznCorechat,
|
||||
});
|
||||
sznCorechatNetwork = await plugins.docker.DockerNetwork.createNetwork(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
Name: this.commonDockerData.networkNames.sznCorechat,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
logger.log('ok', 'sznCorechat is already present');
|
||||
}
|
||||
@ -93,17 +99,23 @@ export class ClusterManager {
|
||||
// Images
|
||||
logger.log('info', `now updating docker images of base services...`);
|
||||
|
||||
const coretrafficImage = await plugins.docker.DockerImage.createFromRegistry(this.coreflowRef.dockerHost, {
|
||||
creationObject: {
|
||||
imageUrl: 'code.foss.global/serve.zone/coretraffic',
|
||||
}
|
||||
});
|
||||
const coretrafficImage = await plugins.docker.DockerImage.createFromRegistry(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
creationObject: {
|
||||
imageUrl: 'code.foss.global/serve.zone/coretraffic',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const corelogImage = await plugins.docker.DockerImage.createFromRegistry(this.coreflowRef.dockerHost, {
|
||||
creationObject: {
|
||||
imageUrl: 'code.foss.global/serve.zone/corelog',
|
||||
}
|
||||
});
|
||||
const corelogImage = await plugins.docker.DockerImage.createFromRegistry(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
creationObject: {
|
||||
imageUrl: 'code.foss.global/serve.zone/corelog',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// SERVICES
|
||||
// lets deploy the base services
|
||||
@ -111,7 +123,7 @@ export class ClusterManager {
|
||||
let coretrafficService: plugins.docker.DockerService;
|
||||
coretrafficService = await plugins.docker.DockerService.getServiceByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
'coretraffic'
|
||||
'coretraffic',
|
||||
);
|
||||
|
||||
if (coretrafficService && (await coretrafficService.needsUpdate())) {
|
||||
@ -123,19 +135,22 @@ export class ClusterManager {
|
||||
}
|
||||
|
||||
if (!coretrafficService) {
|
||||
coretrafficService = await plugins.docker.DockerService.createService(this.coreflowRef.dockerHost, {
|
||||
image: coretrafficImage,
|
||||
labels: {},
|
||||
name: 'coretraffic',
|
||||
networks: [sznCorechatNetwork, sznWebgatewayNetwork],
|
||||
networkAlias: 'coretraffic',
|
||||
ports: ['80:7999', '443:8000'],
|
||||
secrets: [],
|
||||
resources: {
|
||||
memorySizeMB: 1100,
|
||||
volumeMounts: [],
|
||||
coretrafficService = await plugins.docker.DockerService.createService(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
image: coretrafficImage,
|
||||
labels: {},
|
||||
name: 'coretraffic',
|
||||
networks: [sznCorechatNetwork, sznWebgatewayNetwork],
|
||||
networkAlias: 'coretraffic',
|
||||
ports: ['80:7999', '443:8000'],
|
||||
secrets: [],
|
||||
resources: {
|
||||
memorySizeMB: 1100,
|
||||
volumeMounts: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
} else {
|
||||
logger.log('ok', 'coretraffic service is already present');
|
||||
}
|
||||
@ -146,7 +161,7 @@ export class ClusterManager {
|
||||
let corelogService: plugins.docker.DockerService;
|
||||
corelogService = await plugins.docker.DockerService.getServiceByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
'corelog'
|
||||
'corelog',
|
||||
);
|
||||
|
||||
if (corelogService && (await corelogService.needsUpdate())) {
|
||||
@ -157,19 +172,22 @@ export class ClusterManager {
|
||||
}
|
||||
|
||||
if (!corelogService) {
|
||||
corelogService = await plugins.docker.DockerService.createService(this.coreflowRef.dockerHost, {
|
||||
image: corelogImage,
|
||||
labels: {},
|
||||
name: 'corelog',
|
||||
networks: [sznCorechatNetwork],
|
||||
networkAlias: 'corelog',
|
||||
ports: [],
|
||||
secrets: [],
|
||||
resources: {
|
||||
memorySizeMB: 120,
|
||||
volumeMounts: [],
|
||||
corelogService = await plugins.docker.DockerService.createService(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
image: corelogImage,
|
||||
labels: {},
|
||||
name: 'corelog',
|
||||
networks: [sznCorechatNetwork],
|
||||
networkAlias: 'corelog',
|
||||
ports: [],
|
||||
secrets: [],
|
||||
resources: {
|
||||
memorySizeMB: 120,
|
||||
volumeMounts: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
} else {
|
||||
logger.log('ok', 'corelog service is already present');
|
||||
}
|
||||
@ -178,30 +196,48 @@ export class ClusterManager {
|
||||
}
|
||||
|
||||
public async provisionWorkloadService(
|
||||
serviceArgFromCloudly: plugins.servezoneInterfaces.data.IService
|
||||
serviceArgFromCloudly: plugins.servezoneInterfaces.data.IService,
|
||||
) {
|
||||
logger.log('info', `deploying service ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}...`);
|
||||
logger.log(
|
||||
'info',
|
||||
`deploying service ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}...`,
|
||||
);
|
||||
|
||||
// get the image from cloudly
|
||||
logger.log('info', `getting image for ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}`);
|
||||
const containerImageFromCloudly = await this.coreflowRef.cloudlyConnector.cloudlyApiClient.image.getImageById(serviceArgFromCloudly.data.imageId);
|
||||
let localDockerImage: plugins.docker.DockerImage
|
||||
|
||||
logger.log(
|
||||
'info',
|
||||
`getting image for ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}`,
|
||||
);
|
||||
const containerImageFromCloudly =
|
||||
await this.coreflowRef.cloudlyConnector.cloudlyApiClient.image.getImageById(
|
||||
serviceArgFromCloudly.data.imageId,
|
||||
);
|
||||
let localDockerImage: plugins.docker.DockerImage;
|
||||
|
||||
// lets get the docker image for the service
|
||||
if (containerImageFromCloudly.data.location.internal) {
|
||||
const imageStream = await containerImageFromCloudly.pullImageVersion(serviceArgFromCloudly.data.imageVersion);
|
||||
localDockerImage= await plugins.docker.DockerImage.createFromTarStream(this.coreflowRef.dockerHost, {
|
||||
creationObject: {
|
||||
imageUrl: containerImageFromCloudly.id,
|
||||
imageTag: serviceArgFromCloudly.data.imageVersion,
|
||||
const imageStream = await containerImageFromCloudly.pullImageVersion(
|
||||
serviceArgFromCloudly.data.imageVersion,
|
||||
);
|
||||
localDockerImage = await plugins.docker.DockerImage.createFromTarStream(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
creationObject: {
|
||||
imageUrl: containerImageFromCloudly.id,
|
||||
imageTag: serviceArgFromCloudly.data.imageVersion,
|
||||
},
|
||||
tarStream:
|
||||
plugins.smartstream.nodewebhelpers.convertWebReadableToNodeReadable(imageStream),
|
||||
},
|
||||
tarStream: plugins.smartstream.nodewebhelpers.convertWebReadableToNodeReadable(imageStream)
|
||||
});
|
||||
);
|
||||
} else if (
|
||||
containerImageFromCloudly.data.location.externalRegistryId
|
||||
&& containerImageFromCloudly.data.location.externalImageTag
|
||||
containerImageFromCloudly.data.location.externalRegistryId &&
|
||||
containerImageFromCloudly.data.location.externalImageTag
|
||||
) {
|
||||
const externalRegistry = await this.coreflowRef.cloudlyConnector.cloudlyApiClient.externalRegistry.getRegistryById(containerImageFromCloudly.data.location.externalRegistryId);
|
||||
const externalRegistry =
|
||||
await this.coreflowRef.cloudlyConnector.cloudlyApiClient.externalRegistry.getRegistryById(
|
||||
containerImageFromCloudly.data.location.externalRegistryId,
|
||||
);
|
||||
// Lets authenticate against the external registry
|
||||
// TODO: deduplicate this, check wether we are already authenticated
|
||||
await this.coreflowRef.dockerHost.auth({
|
||||
@ -209,12 +245,15 @@ export class ClusterManager {
|
||||
password: externalRegistry.data.password,
|
||||
serveraddress: externalRegistry.data.url,
|
||||
});
|
||||
localDockerImage = await plugins.docker.DockerImage.createFromRegistry(this.coreflowRef.dockerHost, {
|
||||
creationObject: {
|
||||
imageUrl: containerImageFromCloudly.id,
|
||||
imageTag: serviceArgFromCloudly.data.imageVersion,
|
||||
localDockerImage = await plugins.docker.DockerImage.createFromRegistry(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
creationObject: {
|
||||
imageUrl: containerImageFromCloudly.id,
|
||||
imageTag: serviceArgFromCloudly.data.imageVersion,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
await localDockerImage.pullLatestImageFromRegistry();
|
||||
} else {
|
||||
throw new Error('Invalid image location');
|
||||
@ -222,20 +261,20 @@ export class ClusterManager {
|
||||
|
||||
let containerService = await plugins.docker.DockerService.getServiceByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
serviceArgFromCloudly.data.name
|
||||
serviceArgFromCloudly.data.name,
|
||||
);
|
||||
this.coreflowRef.cloudlyConnector.cloudlyApiClient;
|
||||
|
||||
|
||||
const dockerSecretName = `${serviceArgFromCloudly.id}_${serviceArgFromCloudly.data.name}_Secret`;
|
||||
let containerSecret = await plugins.docker.DockerSecret.getSecretByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
dockerSecretName
|
||||
dockerSecretName,
|
||||
);
|
||||
|
||||
// existing network to connect to
|
||||
const webGatewayNetwork = await plugins.docker.DockerNetwork.getNetworkByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
this.commonDockerData.networkNames.sznWebgateway
|
||||
this.commonDockerData.networkNames.sznWebgateway,
|
||||
);
|
||||
|
||||
if (containerService && (await containerService.needsUpdate())) {
|
||||
@ -250,43 +289,55 @@ export class ClusterManager {
|
||||
if (!containerService) {
|
||||
containerSecret = await plugins.docker.DockerSecret.getSecretByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
dockerSecretName
|
||||
dockerSecretName,
|
||||
);
|
||||
if (containerSecret) {
|
||||
await containerSecret.remove();
|
||||
}
|
||||
|
||||
const secretBundle = await this.coreflowRef.cloudlyConnector.cloudlyApiClient.secretbundle.getSecretBundleById(serviceArgFromCloudly.data.secretBundleId);
|
||||
const secretBundle =
|
||||
await this.coreflowRef.cloudlyConnector.cloudlyApiClient.secretbundle.getSecretBundleById(
|
||||
serviceArgFromCloudly.data.secretBundleId,
|
||||
);
|
||||
|
||||
// lets create the relevant stuff on the docker side
|
||||
containerSecret = await plugins.docker.DockerSecret.createSecret(this.coreflowRef.dockerHost, {
|
||||
name: dockerSecretName,
|
||||
contentArg: JSON.stringify(await secretBundle.getFlatKeyValueObjectForEnvironment()),
|
||||
labels: {},
|
||||
version: await containerImageFromCloudly.data.versions[serviceArgFromCloudly.data.imageVersion],
|
||||
});
|
||||
containerService = await plugins.docker.DockerService.createService(this.coreflowRef.dockerHost, {
|
||||
name: serviceArgFromCloudly.data.name,
|
||||
image: localDockerImage,
|
||||
networks: [webGatewayNetwork],
|
||||
secrets: [containerSecret],
|
||||
ports: [],
|
||||
labels: {},
|
||||
resources: serviceArgFromCloudly.data.resources,
|
||||
// TODO: introduce a clean name here, that is guaranteed to work with APIs.
|
||||
networkAlias: serviceArgFromCloudly.data.name,
|
||||
});
|
||||
containerSecret = await plugins.docker.DockerSecret.createSecret(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
name: dockerSecretName,
|
||||
contentArg: JSON.stringify(await secretBundle.getFlatKeyValueObjectForEnvironment()),
|
||||
labels: {},
|
||||
version:
|
||||
await containerImageFromCloudly.data.versions[serviceArgFromCloudly.data.imageVersion],
|
||||
},
|
||||
);
|
||||
containerService = await plugins.docker.DockerService.createService(
|
||||
this.coreflowRef.dockerHost,
|
||||
{
|
||||
name: serviceArgFromCloudly.data.name,
|
||||
image: localDockerImage,
|
||||
networks: [webGatewayNetwork],
|
||||
secrets: [containerSecret],
|
||||
ports: [],
|
||||
labels: {},
|
||||
resources: serviceArgFromCloudly.data.resources,
|
||||
// TODO: introduce a clean name here, that is guaranteed to work with APIs.
|
||||
networkAlias: serviceArgFromCloudly.data.name,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update traffic routing
|
||||
*/
|
||||
public async updateTrafficRouting(clusterConfigArg: plugins.servezoneInterfaces.data.IClusterConfig) {
|
||||
public async updateTrafficRouting(
|
||||
clusterConfigArg: plugins.servezoneInterfaces.data.IClusterConfig,
|
||||
) {
|
||||
const services = await this.coreflowRef.dockerHost.getServices();
|
||||
const webGatewayNetwork = await plugins.docker.DockerNetwork.getNetworkByName(
|
||||
this.coreflowRef.dockerHost,
|
||||
this.commonDockerData.networkNames.sznWebgateway
|
||||
this.commonDockerData.networkNames.sznWebgateway,
|
||||
);
|
||||
const reverseProxyConfigs: plugins.servezoneInterfaces.data.IReverseProxyConfig[] = [];
|
||||
|
||||
@ -294,7 +345,7 @@ export class ClusterManager {
|
||||
serviceNameArg: string,
|
||||
hostNameArg: string,
|
||||
containerDestinationIp: string,
|
||||
webDestinationPort: string
|
||||
webDestinationPort: string,
|
||||
) => {
|
||||
logger.log('ok', `trying to obtain a certificate for ${hostNameArg}`);
|
||||
const certificate =
|
||||
@ -308,7 +359,7 @@ export class ClusterManager {
|
||||
});
|
||||
logger.log(
|
||||
'success',
|
||||
`pushed routing config for ${hostNameArg} on workload service ${serviceNameArg}`
|
||||
`pushed routing config for ${hostNameArg} on workload service ${serviceNameArg}`,
|
||||
);
|
||||
};
|
||||
|
||||
@ -330,7 +381,7 @@ export class ClusterManager {
|
||||
if (!containersOfServicesOnNetwork[0]) {
|
||||
logger.log(
|
||||
'error',
|
||||
`There seems to be no container available for service ${service.Spec.Name}`
|
||||
`There seems to be no container available for service ${service.Spec.Name}`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@ -344,7 +395,7 @@ export class ClusterManager {
|
||||
workloadConfig.name,
|
||||
hostName,
|
||||
containerDestinationIp,
|
||||
webDestinationPort
|
||||
webDestinationPort,
|
||||
);
|
||||
}
|
||||
|
||||
@ -356,14 +407,14 @@ export class ClusterManager {
|
||||
workloadConfig.name,
|
||||
customDomainKey,
|
||||
containerDestinationIp,
|
||||
workloadConfig.ports.custom[customDomainKey]
|
||||
workloadConfig.ports.custom[customDomainKey],
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.log(
|
||||
'ok',
|
||||
`service ${service.Spec.Name} is not a workload service and won't receive traffic`
|
||||
`service ${service.Spec.Name} is not a workload service and won't receive traffic`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ export class InternalServer {
|
||||
|
||||
public async start() {
|
||||
this.typedsocketServer = await plugins.typedsocket.TypedSocket.createServer(
|
||||
this.coreflowRef.typedrouter
|
||||
this.coreflowRef.typedrouter,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ export class CoreflowTaskmanager {
|
||||
await this.updateBaseServicesTask.trigger();
|
||||
logger.log(
|
||||
'success',
|
||||
'initial tasks successfully executed! Now handing over to longterm taskmanager!'
|
||||
'initial tasks successfully executed! Now handing over to longterm taskmanager!',
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
@ -18,7 +18,7 @@ export class CloudlyConnector {
|
||||
public async start() {
|
||||
this.cloudlyApiClient = new plugins.servezoneApi.CloudlyApiClient({
|
||||
registerAs: 'coreflow',
|
||||
cloudlyUrl: await this.coreflowRef.serviceQenv.getEnvVarOnDemand('CLOUDLY_URL')
|
||||
cloudlyUrl: await this.coreflowRef.serviceQenv.getEnvVarOnDemand('CLOUDLY_URL'),
|
||||
});
|
||||
await this.cloudlyApiClient.start();
|
||||
this.coreflowJumpCode = await this.coreflowRef.serviceQenv.getEnvVarOnDemand('JUMPCODE');
|
||||
@ -35,14 +35,12 @@ export class CloudlyConnector {
|
||||
}
|
||||
|
||||
public async getConfigFromCloudly(): Promise<plugins.servezoneInterfaces.data.ICluster> {
|
||||
const config = await this.cloudlyApiClient.getClusterConfigFromCloudlyByIdentity(
|
||||
this.identity
|
||||
);
|
||||
const config = await this.cloudlyApiClient.getClusterConfigFromCloudlyByIdentity(this.identity);
|
||||
return config;
|
||||
}
|
||||
|
||||
public async getCertificateForDomainFromCloudly(
|
||||
domainNameArg: string
|
||||
domainNameArg: string,
|
||||
): Promise<plugins.tsclass.network.ICert> {
|
||||
const certificate = await this.cloudlyApiClient.getCertificateForDomain({
|
||||
identity: this.identity,
|
||||
|
@ -16,15 +16,15 @@ export class CoretrafficConnector {
|
||||
}
|
||||
|
||||
public async setReverseConfigs(
|
||||
reverseConfigsArg: plugins.servezoneInterfaces.data.IReverseProxyConfig[]
|
||||
reverseConfigsArg: plugins.servezoneInterfaces.data.IReverseProxyConfig[],
|
||||
) {
|
||||
await this.start();
|
||||
const reactionRequest =
|
||||
this.coreflowRef.internalServer.typedsocketServer.createTypedRequest<plugins.servezoneInterfaces.requests.routing.IRequest_Coreflow_Coretraffic_RoutingUpdate>(
|
||||
'updateRouting',
|
||||
await this.coreflowRef.internalServer.typedsocketServer.findTargetConnection(
|
||||
async (targetConnection) => targetConnection.alias === 'coretraffic'
|
||||
)
|
||||
async (targetConnection) => targetConnection.alias === 'coretraffic',
|
||||
),
|
||||
);
|
||||
const response = await reactionRequest.fire({
|
||||
reverseConfigs: reverseConfigsArg,
|
||||
|
@ -2,5 +2,5 @@ import * as plugins from './coreflow.plugins.js';
|
||||
|
||||
export const packageDir = plugins.path.join(
|
||||
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
||||
'../'
|
||||
'../',
|
||||
);
|
||||
|
@ -18,7 +18,7 @@ export const runCli = async () => {
|
||||
'info',
|
||||
`trying to start coreflow@v${projectInfoNpm.version} on ${
|
||||
(await smartnetworkInstance.getPublicIps()).v4
|
||||
}`
|
||||
}`,
|
||||
);
|
||||
coreflowInstance = new Coreflow();
|
||||
await coreflowInstance.start();
|
||||
|
@ -6,9 +6,11 @@
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true
|
||||
"verbatimModuleSyntax": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {}
|
||||
},
|
||||
"exclude": [
|
||||
"dist_*/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user