Tuesday, December 17, 2019

Helm Chart for MySQL in GKE

Here is how to deploy and test connectivity of MySQL in Google Kubernetes Engine GKE

# connect to cluster in Google Kubernetes Engine
$ gcloud container clusters get-credentials <your-cluster> --zone <your-zone> --project <your-project>
$ git clone --depth=1 https://github.com/helm/charts.git
$ cd charts/stable/mysql
$ vim values.yaml
$ helm install --name dbserver -f values.yaml stable/mysql
$ kubectl get pods
$ MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default dbserver-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)
$ echo $MYSQL_ROOT_PASSWORD
$ kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
root@ubuntu:/# apt-get update && apt-get install mysql-client -y
root@ubuntu:/#  mysql -h dbserver-mysql -p
mysql> exit
root@ubuntu:/# exit
$ kubectl get pvc
$ kubectl get pv
 
# clean up
$ helm delete --purge dbserver
$ kubectl delete pod/ubuntu

Useful JavaScript Snippets

By using lodash you can loop through arrays and objects with ease

const _ = require("lodash");
// replace object in array
var arr = [{ id: 1, name: "Adam" }, { id: 2, name: "Bob" }];
var index = _.findIndex(arr, { id: 1 });
arr.splice(index, 1, { id: 100, name: "New man" });
document.write(JSON.stringify(arr));
document.write(`<hr/>`);
// update object in array
var mike = { id: 17, name: "mike" };
var newMike = { id: 17, name: "New Mike" };
var updatedMike = _.merge(mike, newMike);
document.write(JSON.stringify(updatedMike));
document.write(`<hr/>`);
// iterate over object using key value
const obj = { a: [76, 23], b: ["en", "es"]}
const result = _.map(obj, (value, key) => {
  document.write(`pair: ${key} : ${value[0]} <br />`);
});
document.write(`<hr/>`);
// filter array of objects by property 
var users = [
  { 'user': 'Adam', 'age': 36, 'active': false },
  { 'user': 'Bob', 'age': 40, 'active': false }
];
var flint = _.filter(users, o => o.age === 40)
document.write(JSON.stringify(flint));
Dealing with undefined in ternary operator

let element;
let item = typeof element === 'undefined' ? 'no val' : element;
  
console.log(item) // no val

Adding an element to a object
    let item = {id: 119 ,name: 'clothing', amount: 45}
 
    // no mutation add at the end of element
    let newItem1 = Object.assign({}, item, {category: 'Personal'})
    console.log(item);
    console.log(newItem1);
 
    // mutate add to end of element
    item = Object.assign(item, {category: 'Personal'});
    console.log(item);
 
    // proces array add at the end of every element
    let collection: any[] = []
    let items = [
      {id: 119 ,name: 'clothing', amount: 45},
      {id: 118 ,name: 'umbrela', amount: 47}
    ]
 
    items.map((item) => collection.push({...item, key4:"val4"}))
    console.log(collection);
Clone and modify existing element in clone. Great for setState in react.
const arrayOfObjects = [
  {name:"adam", isChecked: false},
  {name:"bob", isChecked: false}
]
 
let clone = arrayOfObjects.map((item) => ({...item}));
 
clone.map((item) => item.isChecked = true)
 
clone.map((item)=> console.log("clone ",item.name, item.isChecked))
arrayOfObjects.map((item)=> console.log("arrayOfObjects ",item.name, item.isChecked))

Saturday, November 16, 2019

Images, Containers and Docker Registry

This tutorial shows how to create images and containers and push to hub.docker.com registry. GitHub repo is at https://github.com/nikola-bodrozic/Docker-ReactJS

Simple Build on Linux

Apache web server no Dockerfile, $(pwd) prints path to current folder

docker run -d --name apa -e TZ=UTC -p 8080:80 -v $(pwd)/html/:/var/www/html/ ubuntu/apache2

Development Build

docker build -t reactapp:1.0 .
docker run -p 3000:3000 \ 
       --env REACT_APP_BASE_URL=localhost \ 
       --name react-app reactapp:1.0
docker logs -f YOUR_CONTAINER_SHA

Prod build & push to registry

Create empty private image repo at DOCKER_HUB_USERNAME/REPO_NAME

The repo should be visible in browser at https://hub.docker.com/repository/docker/DOCKER_HUB_USERNAME/REPO_NAME

For production you need to set env variable in Dockerfile-prod not in docker run. Here's how
RUN REACT_APP_BASE_URL=example.com yarn build

build, run and push to registry

docker run -d \
           -p 80:80 \
           --name react-app-prod DOCKER_HUB_USERNAME/REPO_NAME:1.0

docker build -t DOCKER_HUB_USERNAME/REPO_NAME:1.0 \
             -f Dockerfile-prod .

docker login

docker push DOCKER_HUB_USERNAME/REPO_NAME:1.0
DOCKER_HUB_USERNAME/REPO_NAME:1.0

Saturday, June 22, 2019

Override env. variable and shell script

Override env. variable and shell script defined in Docker file in run command.

build an image

docker build -t busybox .

run container with env. variable & run CMD in Dockerfile

docker run busybox

override env. variable in Dockerfile
docker run --env ENV_TARGET=yahoo.com busybox

override CMD in Dockerfile
docker run busybox sh -c 'whoami && pwd'

Dockerfile

FROM busybox

WORKDIR /app
ENV ENV_TARGET google.com
COPY subs.sh subs.sh
RUN chmod +x subs.sh
CMD ["/app/subs.sh"]

subs.sh

#!/bin/sh

ping -c 2 ${ENV_TARGET}

axios concurrent calls

Axios can make multiple concurrent calls. In app.js calls to two end-points are started at the same time so total waiting time is 4 seconds. Server latency is 4 seconds for demo purposes.

app.js

const axios = require('axios')
 
try {
    console.log("start");
    function getUserName() {
        return axios.get('http://localhost:3000/heroes');
    }
 
    function getId() {
        return axios.get('http://localhost:3000/heroes');
    }
 
    // Performing multiple concurrent requests waiting time 4 seconds
    axios.all([getUserName(), getId()])
        .then(axios.spread(function (acct, perms) {
            const user = acct.data[0].param;
            const id = perms.data[1].param;
            console.log(`${user} ${id}`)
            const str = 'https://jsonplaceholder.typicode.com/' + user + '/' + id
            console.log(str)
            axios.get(str).then(response => console.log(response.data.name));
        }));
} catch (error) {
    console.error(error);
}

Monday, June 17, 2019

axios async await

Sometimes you need to wait for one (axios) call to finish to continue with next one. It's accomplished by using async/await. Last axios call in app.js downloads a file without waiting for getUser() to be finished.

set server delay to 4 seconds for demo purposes

{
  "name": "async-await",
  "scripts": {
    "serve-json": "json-server --delay 4000 --watch db.json",
    "start": "node app.js"
  },
  "dependencies": {
    "axios": "^0.19.0",
    "json-server": "^0.15.0"
  }
}

db.json

{
    "heroes": [
        {
            "param": "users"
        },
        {
            "param": "1"
        }
    ]
}

app.js

const axios = require('axios')
const fs = require('fs')
 
async function getUser() {
    try {
        console.log("start");
        const response = await axios.get('http://localhost:3000/heroes');
        var1 = response.data[0].param; // users
        console.log("4 sec after start ", var1);
        const response2 = await axios.get('http://localhost:3000/heroes');
        var2 = response2.data[1].param; // 1
        console.log("8 sec after start", var2);
        const response3 = await axios.get('https://jsonplaceholder.typicode.com/' + var1 + '/' + var2);
        console.log(response3.data.name);
    } catch (error) {
        console.error(error);
    }
}
 
getUser()
 
// call below doesnot wait for getUser() to be finished 
axios({
    method: 'get',
    url: 'https://jsonplaceholder.typicode.com/users/2',
    responseType: 'stream'
  })
    .then(function (response) {
      response.data.pipe(fs.createWriteStream('full-user.json'))
});






Thursday, February 14, 2019

Oracle 12c Create Table with Auto Increment and Flashback

CREATE TABLE table_name ( 
    id NUMBER(10) GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 NOCACHE ) NOT NULL, 
    ctimestamp TIMESTAMP DEFAULT current_timestamp 
) NOLOGGING; 

CREATE UNIQUE INDEX table_name_pk ON table_name (id ASC ); 

ALTER TABLE table_name ADD CONSTRAINT table_name_pk PRIMARY KEY ( id ); 

SELECT TO_CHAR (SYSDATE, 'YYYY-MM-DD HH24:MI:SS') "NOW" FROM DUAL; 

CREATE TABLESPACE archivetest_tabspace DATAFILE SIZE 10M SEGMENT SPACE MANAGEMENT AUTO; 

CREATE FLASHBACK ARCHIVE archivetest TABLESPACE archivetest_tabspace QUOTA 50M RETENTION 7 DAY; 

ALTER TABLE table_name FLASHBACK ARCHIVE archivetest; 

SELECT * FROM table_name AS OF TIMESTAMP TO_TIMESTAMP ('2018-11-29 14:05:11', 'YYYY-MM-DD HH24:MI:SS');

Sunday, January 6, 2019

Docker and node_modules

Development environment for a NodeJS App


Dockefile

FROM node:16-alpine

WORKDIR /app

COPY package.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

.dockerignore

node_modules
npm-debug.log
.git
Dockerfile
.dockerignore

Open your browser on http://localhost:3000

docker-compose.yaml
version: "3.8"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - './src:/app/src'
      - './public/assets:/app/public/assets'
      - '/app/node_modules'
    ports:
      - 3000:3000
    stdin_open: true
    environment:
      - CHOKIDAR_USEPOLLING=true