From ba69f2f8aab3410c71c8df2ac23d433c3fda8d85 Mon Sep 17 00:00:00 2001 From: Miguel de Barros Date: Tue, 17 Oct 2023 19:21:57 +0100 Subject: [PATCH] docs: added tools for devspace --- .nvmrc | 1 + package-lock.json | 8 +- package.json | 8 +- src/.vuepress/config.js | 15 +- src/NodeJS/development/tools/devspace.md | 136 ++++++++++++++ .../development/tools/devspace_config.md | 167 ++++++++++++++++++ .../development/tools/devspace_script.md | 77 ++++++++ src/NodeJS/development/tools/readme.md | 10 ++ 8 files changed, 419 insertions(+), 3 deletions(-) create mode 100644 .nvmrc create mode 100644 src/NodeJS/development/tools/devspace.md create mode 100644 src/NodeJS/development/tools/devspace_config.md create mode 100644 src/NodeJS/development/tools/devspace_script.md create mode 100644 src/NodeJS/development/tools/readme.md diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..b6a7d89 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +16 diff --git a/package-lock.json b/package-lock.json index 34bea50..ec7da51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,8 +5,9 @@ "requires": true, "packages": { "": { + "name": "reference-architecture", "version": "0.0.1", - "license": "MIT", + "license": "Apache-2.0", "dependencies": { "markdown-it-footnote": "^3.0.3", "markdown-it-multimd-table": "^4.1.3", @@ -14,6 +15,9 @@ }, "devDependencies": { "vuepress": "^1.5.3" + }, + "engines": { + "node": "16.x" } }, "node_modules/@ampproject/remapping": { @@ -15994,6 +15998,7 @@ "integrity": "sha512-iFv9J3F5VKUPcbx+TqW5qhGmAVyXQxPRpKpPOuTLFIVTzg+iwJnrqVbL4kJU5ECGDxPESW2oCVgxv9bTlDPu7w==", "dev": true, "requires": { + "@babel/core": "^7.11.0", "@babel/helper-compilation-targets": "^7.9.6", "@babel/helper-module-imports": "^7.8.3", "@babel/plugin-proposal-class-properties": "^7.8.3", @@ -16006,6 +16011,7 @@ "@vue/babel-plugin-jsx": "^1.0.3", "@vue/babel-preset-jsx": "^1.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", + "core-js": "^3.6.5", "core-js-compat": "^3.6.5", "semver": "^6.1.0" } diff --git a/package.json b/package.json index 8c51e3a..f4ccf81 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,16 @@ "version": "0.0.1", "description": "The goal of the reference architecture is to present", "main": "index.js", + "engines": { + "node": "16.x" + }, "authors": { "name": "Paul Baker", - "email": "paul.baker@modusbox.com" + "email": "paul.baker@infitx.com" }, + "contributors": [ + "Miguel de Barros " + ], "repository": "reference-architecture/reference-architecture", "scripts": { "dev": "vuepress dev src --no-cache", diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index e00463e..1208aea 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -114,7 +114,20 @@ module.exports = { '/NodeJS/development/protecting-code', '/NodeJS/development/secure-development-process', '/NodeJS/development/testing', - '/NodeJS/development/typescript' + '/NodeJS/development/typescript', + { + title: "NodeJS Tools", + path: '/NodeJS/development/tools/', + children :[ + { + title: "Devspace", + path: '/NodeJS/development/tools/', + children :[ + '/NodeJS/development/tools/devspace', + '/NodeJS/development/tools/devspace_config', + '/NodeJS/development/tools/devspace_script' + ]}, + ]} ]}, { title: "Functional Components", diff --git a/src/NodeJS/development/tools/devspace.md b/src/NodeJS/development/tools/devspace.md new file mode 100644 index 0000000..301ea3b --- /dev/null +++ b/src/NodeJS/development/tools/devspace.md @@ -0,0 +1,136 @@ +# Example using Devspace for Central-Ledger + +[Devspace](https://www.devspace.sh/) will allow you to run and debug code within a live Kubernetes environment. + +The method shown below can be applied to any services with some minor tweaks/changes. + +## References + +1. original version of this document: https://gist.github.com/mdebarros/01ad36506ecc079753acd18d2dd4cabf +2. similar (possibly out-dated) gist that I shared in the past: https://gist.github.com/mdebarros/0b0818189a277679cc7a01049f81b0fa#file-devspace-md + +## Install Devspace + +Install [Devspace](https://www.devspace.sh/) --> https://www.devspace.sh/docs/getting-started/installation + +## Setup + +1. Copy [devspace.yaml](./devspace_config.md) to the root folder, making sure to edit the confg to match your environment + - IMAGE / REPLACE_IMAGE vars - make sure it matches the Alpine Nodejs Docker image version as in your `nvmrc` file with format as `node:{{NODE_VERSION}}-alpine` (e.g. `node:18.17.1-alpine`) + - LABEL_NAME var - make sure it matches the sub-prefix name of your desired deployment label for `app.kubernetes.io/name` (refer to /.devspace/deployment.yaml - see below for more info) + - LABEL_INSTANCE var - make sure it matches the name of your deployment label for `app.kubernetes.io/instance` (refer to /.devspace/deployment.yaml - see below for more info) +2. Copy [devspace_start.sh](./devspace_script.md) to the root folder +3. Create a `.devspace` folder +4. Dump desired Central-ledger `deployment.yaml` using the following example into the `.devspace` folder + + ```bash + kubectl -n moja2 get deployment moja2-centralledger-handler-transfer-fulfil -o yaml > ./.devspace/deployment.yaml + ``` + +## Configure VS Code with the following debug targert + +Save the following config in `.vscode/launch.json` + +```json +{ + // 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": "Attach to Process @9229", + "type": "node", + "request": "attach", + "port": 9229, + "remoteRoot": "/opt/app/" + } + ] +} +``` + +## Run Devspace + +```bash +devspace dev +``` + +This will deploy a new deployment with the same name as the target deployment, except it will have a `devspace` suffix at the end. E.g. `moja2-centralledger-handler-transfer-fulfil-devspace`. + +```bash +❯ kubectl -n moja2 get deployment | grep fulfil +moja2-centralledger-handler-transfer-fulfil 0/0 0 0 51m <-- NOTE: This has been scaled to 0. +moja2-centralledger-handler-transfer-fulfil-devspace 1/1 1 1 17h +``` + +If you want to revert, then + +1. Exit the devspace process in your terminal, +2. Delete the `moja2-centralledger-handler-transfer-fulfil-devspace` deployment, and +3. Scale the `moja2-centralledger-handler-transfer-fulfil` deployment from `0` to `1` + +### Running Service + +Once the devspace service has fully started and synchronised the filesystem from your local to remote, it will + +1. Execute the [devspace_start.sh](src/NodeJS/development/tools/assets/devspace_start.sh) file (which currently installs OS and NPM dependencies) +2. Print out some sample instructions/commands on how to start the Central-Ledger service as found in the [devspace_start.sh](src/NodeJS/development/tools/assets/devspace_start.sh) + +You can also refer to the `deployment.yaml` for the container command: + + ```yaml + spec: + containers: + - command: + - node + - src/handlers/index.js + - handler + - --fulfil + ``` + + You can execute it in your pod terminal like so: + + ```bash + node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil + ``` + + > Note: `--inspect=0.0.0.0:9229` argument to start the service in debug mode (ensure that you have added the debug port to the `deployment.yaml`. + +If you need to attach a debugger on startup, then use `--inspect-brk=0.0.0.0:9229` instead. + +If youare missing some stdout statements, you can override the `CSL_LOG_TRANSPORT` (which is generally set to `file`) to `console` - This will ensure that all log statements are printed to your stdout. + + ```bash + CSL_LOG_TRANSPORT=console node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil + ``` + + You can also override the `LOG_LEVEL`. + + ```bash + LOG_LEVEL=debug CSL_LOG_TRANSPORT=console node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil + ``` + +## Debugging + +Once the service has been started, execute the `Attach to Process @9229` process in VSCode, and you should see your Pod stdout show + +```bash +Debugger attached. +``` + +Overally it should look something like this: + +```bash +$ node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil +Debugger listening on ws://0.0.0.0:9229/97ecb806-186a-4448-99c9-5d9b417e2f8d <-- NOTE: Indicates that debugger has started +For help, see: https://nodejs.org/en/docs/inspector +(node:2151) [MONGODB DRIVER] Warning: promiseLibrary is a deprecated option +(Use `node --trace-warnings ...` to show where the warning was created) +http://moja3-cl-handler-bulk-transfer-fulfil-fc84f74fc-w6426-q2hn8:3001 +method path description +------ -------- --------------------------- +GET /health +GET /metrics Prometheus metrics endpoint + +Debugger attached. <-- NOTE: This indicates that your debugger has attached successfully! +``` diff --git a/src/NodeJS/development/tools/devspace_config.md b/src/NodeJS/development/tools/devspace_config.md new file mode 100644 index 0000000..36c55dd --- /dev/null +++ b/src/NodeJS/development/tools/devspace_config.md @@ -0,0 +1,167 @@ +# File: devspace.yaml + +```yaml +## INSTRUCTIONS: +## cmd: devspace dev +## + +version: v1beta10 + +# `vars` specifies variables which may be used as ${VAR_NAME} in devspace.yaml +vars: + - name: IMAGE + value: node:18.17.1-alpine + - name: WORKDIR + value: /opt/app + - name: LABEL_NAME + # value: &LABEL_NAME centralledger-handler-admin-transfer + # value: &LABEL_NAME centralledger-handler-transfer-prepare + value: &LABEL_NAME centralledger-handler-transfer-fulfil + # value: &LABEL_NAME cl-handler-bulk-transfer-fulfil + # value: &LABEL_NAME cl-handler-bulk-transfer-prepare + # value: &LABEL_NAME centralledger-handler-transfer-position + # value: &LABEL_NAME centralledger-handler-timeout + - name: LABEL_INSTANCE + # value: moja1 + value: moja2 + # value: moja3 + # value: dev3 + - name: DEPLOYMENT_NAME + value: *LABEL_NAME + - name: CONTAINER_NAME + value: *LABEL_NAME + - name: REPLACE_IMAGE + value: node:18.17.1-alpine + +# `deployments` tells DevSpace how to deploy this project +deployments: +- name: ${LABEL_INSTANCE}-${DEPLOYMENT_NAME} + # This deployment uses `kubectl` but you can also define `helm` deployments + kubectl: + manifests: + - .devspace/deployment.yaml + +# `dev` only applies when you run `devspace dev` +dev: + # `dev.ports` specifies all ports that should be forwarded while `devspace dev` is running + # Port-forwarding lets you access your application via localhost on your local machine + ports: + - labelSelector: + app.kubernetes.io/name: ${LABEL_NAME} + app.kubernetes.io/instance: ${LABEL_INSTANCE} + # - imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}` + forward: + - port: 3001 + - port: 9229 + remotePort: 9229 + + # `dev.open` tells DevSpace to open certain URLs as soon as they return HTTP status 200 + # Since we configured port-forwarding, we can use a localhost address here to access our application + # open: + # - url: http://localhost:3007 + + # `dev.sync` configures a file sync between our Pods in k8s and your local project files + sync: + - labelSelector: + app.kubernetes.io/name: ${LABEL_NAME} + app.kubernetes.io/instance: ${LABEL_INSTANCE} + # - imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}` + disableDownload: true + # waitInitialSync: false + # polling: false + containerPath: ${WORKDIR} + localSubPath: ./ + excludePaths: + - .git/ + - config/ + - secrets/ + - test/ + # downloadExcludePaths: + # - config/ + uploadExcludePaths: + - deploy/ + # - config/ + - coverage/ + - node_modules/ + - .dockerignore + - .editorconfig + - .istanbul.yml + - circle.yml + - docker-compose.circle.yml + - docker-compose.dev.yml + - docker-compose.functional.yml + - docker-compose.yml + - Dockerfile + - LICENSE + - sonar-project.properties + + # `dev.terminal` tells DevSpace to open a terminal as a last step during `devspace dev` + terminal: + labelSelector: + app.kubernetes.io/name: ${LABEL_NAME} + app.kubernetes.io/instance: ${LABEL_INSTANCE} + # imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}` + # With this optional `command` we can tell DevSpace to run a script when opening the terminal + # This is often useful to display help info for new users or perform initial tasks (e.g. installing dependencies) + # DevSpace has generated an example ./devspace_start.sh file in your local project - Feel free to customize it! + workDir: ${WORKDIR} + command: + - sh + - devspace_start.sh + + # Since our Helm charts and manifests deployments are often optimized for production, + # DevSpace let's you swap out Pods dynamically to get a better dev environment + replacePods: + - labelSelector: + app.kubernetes.io/name: ${LABEL_NAME} + app.kubernetes.io/instance: ${LABEL_INSTANCE} + containerName: ${CONTAINER_NAME} + # - imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}` + # Since the `${IMAGE}` used to start our main application pod may be distroless or not have any dev tooling, let's replace it with a dev-optimized image + # DevSpace provides a sample image here but you can use any image for your specific needs + # replaceImage: loftsh/javascript:latest + replaceImage: ${REPLACE_IMAGE} + # Besides replacing the container image, let's also apply some patches to the `spec` of our Pod + # We are overwriting `command` + `args` for the first container in our selected Pod, so it starts with `sleep 9999999` + # Using `sleep infinity` as PID 1 (instead of the regular ENTRYPOINT), allows you to start the application manually + patches: + # Lets replace the container command with `sleep infinity` so that the container does not start the application automatically + - op: replace + path: spec.containers[0].command + value: + - sleep + - op: replace + path: spec.containers[0].args + value: + - infinity + - op: add + path: spec.containers[0].ports + value: + containerPort: 9229 + name: debug + protocol: TCP + # Remove securityContext + - op: remove + path: spec.containers[0].securityContext + # Remove Readiness and Liveness probes + - op: remove + path: spec.containers[0].readinessProbe + - op: remove + path: spec.containers[0].livenessProbe + - op: remove + path: spec.containers[1].readinessProbe + - op: remove + path: spec.containers[1].livenessProbe + +# `profiles` lets you modify the config above for different environments (e.g. dev vs production) +profiles: + # This profile is called `production` and you can use it for example using: devspace deploy -p production + # We generally recommend to use the base config without any profiles as optimized for development (e.g. image build+push is disabled) +- name: production +# This profile adds our image to the config so that DevSpace will build, tag and push our image before the deployment + merge: + images: + app: + image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above) + dockerfile: ./Dockerfile +``` diff --git a/src/NodeJS/development/tools/devspace_script.md b/src/NodeJS/development/tools/devspace_script.md new file mode 100644 index 0000000..c8f2975 --- /dev/null +++ b/src/NodeJS/development/tools/devspace_script.md @@ -0,0 +1,77 @@ +# File: devspace_start.sh + +```bash +#!/bin/bash +set +e # Continue on errors + +echo "Installing dependencies" + +# apk add --no-cache -t build-dependencies make gcc g++ python3 libtool libressl-dev openssl-dev autoconf automake +apk add --no-cache -t build-dependencies make gcc g++ python3 libtool openssl-dev autoconf automake bash + +npm install -g node-gyp + +apk add --no-cache -t ngrep + +npm ci + +## Example of how to install dependencies based on the lockfile type +# export NODE_ENV=development +# if [ -f "yarn.lock" ]; then +# echo "Installing Yarn Dependencies" +# # yarn +# else +# if [ -f "package.json" ]; then +# echo "Installing NPM Dependencies" +# npm install -g npm@latest-6 +# npm install +# fi +# fi + +COLOR_CYAN="\033[0;36m" +COLOR_RESET="\033[0m" + +echo -e "${COLOR_CYAN} + ____ ____ + | _ \ _____ __/ ___| _ __ __ _ ___ ___ + | | | |/ _ \ \ / /\___ \| '_ \ / _\` |/ __/ _ \\ + | |_| | __/\ V / ___) | |_) | (_| | (_| __/ + |____/ \___| \_/ |____/| .__/ \__,_|\___\___| + |_| +${COLOR_RESET} +Welcome to your development container! + +This is how you can work with it: +- Run \`${COLOR_CYAN}npm start${COLOR_RESET}\` to start the application +- Run \`${COLOR_CYAN}npm run dev${COLOR_RESET}\` to start hot reloading +- ${COLOR_CYAN}Files will be synchronized${COLOR_RESET} between your local machine and this container +- Some ports will be forwarded, so you can access this container on your local machine via ${COLOR_CYAN}localhost${COLOR_RESET}: + +Use ngrep if you want to monitor inbound & outbound HTTP traffic using the following command: ngrep -qt 'HTTP' + +Run the following to start the application: + node --inspect=0.0.0.0:9229 src/api/index.js + node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil + node --inspect=0.0.0.0:9229 src/handlers/index.js handler --prepare --position --fulfil + CSL_LOG_TRANSPORT="" node --inspect=0.0.0.0:9229 src/handlers/index.js handler --prepare --position --fulfil + + CSL_LOG_TRANSPORT="" node --inspect=0.0.0.0:9229 src/handlers/index.js handler --bulkprepare + CSL_LOG_TRANSPORT="" node --inspect=0.0.0.0:9229 src/handlers/index.js handler --bulkfulfil + + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug node --inspect=0.0.0.0:9229 src/handlers/index.js handler --bulkprepare + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug nohup node --inspect=0.0.0.0:9229 src/handlers/index.js handler --bulkprepare > console.log & + + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug node --inspect=0.0.0.0:9229 src/handlers/index.js handler --position + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug nohup node --inspect=0.0.0.0:9229 src/handlers/index.js handler --position > console.log & + + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug node --inspect=0.0.0.0:9229 src/handlers/index.js handler --timeout + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug nohup node --inspect=0.0.0.0:9229 src/handlers/index.js handler --timeout > console.log & + + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug node --inspect=0.0.0.0:9229 src/handlers/index.js handler --bulkfulfil + CSL_LOG_TRANSPORT=console LOG_LEVEL=debug nohup node --inspect=0.0.0.0:9229 src/handlers/index.js handler --bulkfulfil > console.log & +" + +# bash +sh + +``` diff --git a/src/NodeJS/development/tools/readme.md b/src/NodeJS/development/tools/readme.md new file mode 100644 index 0000000..400b2d5 --- /dev/null +++ b/src/NodeJS/development/tools/readme.md @@ -0,0 +1,10 @@ +--- +sidebar_position: 1 +slug: / +--- + +# Node.js Tools + +## Overview + +Here you will find a list of useful NodeJS specific tooling.