Skip to main content

Web Components

· One min read

Open in Notion

HTMLSlotElement

The HTMLSlotElement interface of the Shadow DOM API enables access to the name and assigned nodes of an HTML <slot> element.

Life Cycle Callbacks

Special callback functions defined inside the custom element's class definition, which affect its behavior:

connectedcallback

Invoked when the custom element is first connected to the document's DOM.

disconnectedcallback

Invoked when the custom element is disconnected from the document's DOM.

adoptedcallback

Invoked when the custom element is moved to a new document.

attributechangedcallback

Invoked when one of the custom element's attributes is added, removed, or changed.

CSS pseudo-classes

:defined {}
:host {}
:host() {}
:host-context() {}

Access parent element

<wc-parent>
<wc-child>
<wc-subchild>
</wc-subchild>
</wc-child>
<wc-parent>
function findParent(startElement: Element | ShadowRoot, selector: string): Element | null {
let result: Element | null;
if (startElement instanceof HTMLElement) {
result = startElement.closest(selector);
if (result) {
return result;
}
}
const r = startElement.getRootNode();
if (r instanceof ShadowRoot) {
return findParent((r as ShadowRoot).host, selector);
}
return null;
}

// wc-subchild component
findParent(this.shadowRoot, 'wc-parent');

ngrok

· One min read

Open in Notion

Installation

bookmark

Commands

Run an instance

# start in background and forward to https://localhost:3000
nohup ./ngrok http https://localhost:3000 &

Get Tunnels

curl \
-X GET \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/tunnels

Response

{
"tunnels": [
{
"id": "tn_2NTVGqGpa5w2LExRzILEksu7FOa",
"public_url": "https://b8ad9cf4eff6.ngrok.paid",
"started_at": "2023-03-24T19:59:25Z",
"proto": "https",
"region": "us",
"tunnel_session": {
"id": "ts_2NTVGmVw5yMzr02ZZzlX4VC6b6L",
"uri": "https://api.ngrok.com/tunnel_sessions/ts_2NTVGmVw5yMzr02ZZzlX4VC6b6L"
},
"endpoint": {
"id": "ep_2NTVGqGpa5w2LExRzILEksu7FOa",
"uri": "https://api.ngrok.com/endpoints/ep_2NTVGqGpa5w2LExRzILEksu7FOa"
},
"forwards_to": "http://localhost:80"
},
{
"id": "tn_2NTVGiqsZQ8EGqJ7HgcysTvGPAN",
"public_url": "://:0",
"started_at": "2023-03-24T19:59:24Z",
"region": "us",
"tunnel_session": {
"id": "ts_2NTVGfpxBknN9h3rpLqPiV7NiAw",
"uri": "https://api.ngrok.com/tunnel_sessions/ts_2NTVGfpxBknN9h3rpLqPiV7NiAw"
},
"labels": {
"baz": "qux",
"foo": "bar"
},
"forwards_to": "http://localhost:80"
}
],
"uri": "https://api.ngrok.com/tunnels",
"next_page_uri": null
}

Get Tunnel

curl \
-X GET \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/tunnels/tn_2NTVGqGpa5w2LExRzILEksu7FOa

Response

{
"id": "tn_2NTVGqGpa5w2LExRzILEksu7FOa",
"public_url": "https://b8ad9cf4eff6.ngrok.paid",
"started_at": "2023-03-24T19:59:25Z",
"proto": "https",
"region": "us",
"tunnel_session": {
"id": "ts_2NTVGmVw5yMzr02ZZzlX4VC6b6L",
"uri": "https://api.ngrok.com/tunnel_sessions/ts_2NTVGmVw5yMzr02ZZzlX4VC6b6L"
},
"endpoint": {
"id": "ep_2NTVGqGpa5w2LExRzILEksu7FOa",
"uri": "https://api.ngrok.com/endpoints/ep_2NTVGqGpa5w2LExRzILEksu7FOa"
},
"forwards_to": "http://localhost:80"
}

Commands for Terminal

· 2 min read

Open in Notion

Useful Aliases

Add following aliases in your ~/.bash_profile

alias ..='cd ..'
alias ...='cd ../../'
alias b='brew'
alias c='clear'
alias l='ls -lah'
alias su='sudo -i'
alias root='sudo -i'

How to parse JSON string in the terminal

Install jq via following link to parse the string.

bookmark

curl 'https://api.github.com/repos/jqlang/jq/commits?per_page=5' | jq '.[0]'

How to find the largest files or folders on a file system

To find the largest folders on a file system pass the -a option. This will change the behavior of du to write size counts for files as well as folders. Run the following as root to see the ten largest files or folders on a system. This can be useful if you are dealing with out-of-disk space issues on a system.

du -a / | sort -n -r | head -n 10
5351116 /
2462616 /usr
2153492 /home
2153472 /home/george
1571924 /usr/lib

How to sort by file or folder size

To sort by file size pass the output of du to sort and use the -n (numeric) and -r (reverse) options.

du ~/go | sort -n -r | less
170440 /home/george/go
132816 /home/george/go/src
74024 /home/george/go/src/github.com
57072 /home/george/go/src/golang.org

Open and close ports on RHEL 8 / CentOS 8

sudo firewall-cmd --zone=public --list-ports
sudo firewall-cmd --zone=public --permanent --add-port 8080/tcp
sudo firewall-cmd --reload

sudo firewall-cmd --zone=public --permanent --remove-port 8080/tcp

Podman

· 2 min read

Open in Notion

The alternative of docker as docker is no longer free for enterprise users.

Installation

bookmark

Install from download

wget https://github.com/containers/podman/releases/latest/download/podman-remote-static-linux_amd64.tar.gz
tar -xvzf podman-remote-static-linux_amd64.tar.gz
sudo mv ./bin/podman-remote-static-linux_amd64 /usr/local/bin/podman
sudo chmod +x /usr/local/bin/podman

Examples

# If you want to keep your existing volumns, you should use --userns=keep-id,
# otherwise, it might throw "operation not permitted" when start a container
podman run -d --name my-container --userns=keep-id \
-v /your-path:/path
image-name

Configure sources

Open /etc/containers/registries.conf and uncomment below line, so that you can pull images from other sources.

unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "docker.io"]

Jenkins in Podman

Run podman in jenkins pipeline if jenkins is running in container

Mount the socket of podman into jenkins container.

docker run -d \
--name my-jenkins \
-p 8080:8080 \
-v /home/<host_user>/jenkins_home:/var/jenkins_home \
-v /run/user/1000/podman/podman.sock:/run/user/1000/podman/podman.sock \
bndynet/jenkins

Then run it in pipeline:

pipeline {
agent any
stages {
stage('Run Podman') {
steps {
sh 'export PODMAN_HOST=unix:///run/user/1000/podman/podman.sock && podman run --rm hello-world'
}
}
}
}

Let jenkins account run podman

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 jenkins

If the jenkins user does not exist, please create one:

sudo useradd -m -s /bin/bash jenkins
sudo passwd jenkins # set password(optional)

Restart jenkins

sudo systemctl restart jenkins
# or podman restart jenkins-container

Automatically Start

Podman provides generate systemd command, that can generate systemd service file to restart when server starts.

podman generate systemd --name my-container --restart-policy=always > /etc/systemd/system/my-container.service

Then enable and start service:

systemctl daemon-reload
systemctl enable my-container
systemctl start my-container

In this way, my-container will start automatically, it likes docker --restart unless-stopped.

Q&A

Can not “podman machine start”?

You need to remove the current machine via podman machine rm. and reinit via podman machine init.

PostgreSQL

· 3 min read

Open in Notion

Installing

bookmark

# default
docker run --name my-postgres -e POSTGRES_PASSWORD=your-pass -d postgres

# advance
docker run -d --name my-postgres \
-v /my-dockers/my-postgres/my-postgres.conf:/etc/postgresql/postgresql.conf \
-v /my-dockers/my-postgres/data:/var/lib/postgresql/data \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-e POSTGRES_PASSWORD=your-pass \
-e POSTGRES_USER=postgres \
-e POSTGRES_DB=my-db \
-c ssl=on \
-p 5432:5432 \
postgres -c 'config_file=/etc/postgresql/postgresql.conf'

via psql:

$ docker run -it --rm --network some-network postgres psql -h my-postgres -U postgres
psql (14.3)
Type "help" for help.

postgres=# SELECT 1;
?column?
----------
1
(1 row)

Generate SSL Certificates for PostgreSQL server

  1. Go to data folder

    cd /var/lib/postgresql/data/pgdata
  2. Generate a private key by entering a pass phrase:

    openssl genrsa -des3 -out server.key 2048
  3. Remove the pass phrase to automatically start up the server using the following command

    openssl rsa -in server.key -out server.key
  4. Run the following command to remove group and other’s permission from the private key file

    chmod og-rwx server.key
  5. Run the following command to create a self-signed certificate

    openssl req -new -key server.key -days 3650 -out server.crt -x509

    Note that: You will be asked to enter information that will be incorporated into your certificate request. For some fields, there will be a default value. If you enter ‘.’, the field will be left blank.

    Country Name (2 letter code) [XX]:IN
    State or Province Name (full name) []:.
    Locality Name (eg, city) [Default City]:CH
    Organization Name (eg, company) [Default Company Ltd]:francium tech Organizational Unit Name (eg, section) []:.
    Common Name (eg, your name or your server's hostname) []:.
    Email Address []:kumaresan@francium.tech
  6. For self-signed certificates, use the server certificate as the trusted root certificate:

    cp server.crt root.crt

Prepare PostgreSQL standalone for SSL authentication

  1. Edit the postgresql.conf file to activate SSL:

    cd /usr/local/var/postgres
    vi postgresql.conf
  2. Uncomment and change the following parameters:

    ssl = on
    ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
    ssl_prefer_server_ciphers = on
    ssl_cert_file = 'server.crt'
    ssl_key_file = 'server.key'
    ssl_ca_file = 'root.crt'
    ssl_crl_file = ''
  3. Add the following entry to the client machine in /var/lib/postgresql/data/pgdata/pg_hba.conf file:

    local all all trust
    hostssl all all 127.0.0.1/32 cert
    hostnossl all all 0.0.0.0/0 reject
    hostnossl all all ::/0 reject
  4. To verify if SSL is enabled on standalone Postgres, run the following command:

    psql 'host=\<hostname\> port=5432 dbname=\<name\> user=\<user\> sslmode=verify-full sslcert=/tmp/postgresql.crt sslkey=/tmp/postgresql.key sslrootcert=/tmp/root.crt'
  5. Once the database has restarted, login by specifying localhost to make sure the database is being connected over TCP/IP:

    psql -h localhost -U postgres

Update Jenkins inside Docker Container

· One min read

Open in Notion

First identify your image.

$ docker ps --format "{{.ID}}: {{.Image}} {{.Names}}"3d2fb2ab2ca5: jenkins-docker jenkins-docker_1

Then login into the image as root.

$ docker container exec -u 0 -it jenkins-docker_1 /bin/bash

Now you are inside the container, download the jenkins.war file from the official site like.

# wget http://updates.jenkins-ci.org/download/war/2.176.1/jenkins.war

Replace the version with the one that fits to you.

The next step is to move that file and replace the oldest one.

# mv ./jenkins.war /usr/share/jenkins/

Then change permissions.

# chown jenkins:jenkins /usr/share/jenkins/jenkins.war

The last step is to logout from the container and restart it.

$ docker restart jenkins-docker_1

You can verify that update was successful by access to you Jenkins url.

Tmux

· One min read

Open in Notion

Installing

bookmark

Script Examples

Start a main pane with other panes

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ +
+ main +
+ +
+ +
+ +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ a + b + c +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tmux new-session -d -s sessionName; \
tmux split-window -v; \
tmux send-keys "echo a" Enter; \
tmux split-window -v; \
tmux send-keys "echo b" Enter; \
tmux split-window -v; \
tmux send-keys "echo c" Enter; \
tmux select-layout main-horizontal; \
tmux select-pane -t 0; \
tmux a;

Start there same size panes

tmux new-session -d -s sessionName; \
tmux send-keys "echo a" Enter; \
tmux split-window -v; \
tmux send-keys "echo b" Enter; \
tmux split-window -v; \
tmux send-keys "echo c" Enter; \
tmux select-layout even-horizontal; \
tmux a;

Others

# Layouts
tmux select-layout main-vertical
tmux select-layout main-horizontal
tmux select-layout even-vertical
tmux select-layout even-horizontal

# Enable pane border labels
tmux set pane-border-status top

#Enable Mouse
tmux set mouse on

Oh my tmux

https://github.com/gpakosz/.tmux

Do not forget to source your config file via:

tmux source-file ~/.tmux.conf.local

Useful Scripts for Jenkins

· One min read

Open in Notion

Decrypt credentials defined in Jenkins and list values.

def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
Jenkins.instance,
null,
null
);
for (c in creds) {
if (c.properties.privateKeySource) {
println("ID: " + c.id)
println("UserName: " + c.username)
println("Description: " + c.description)
println("Private Key: " + c.getPrivateKey() )
}
}

Decrypt the password if you got its HASH.

println(hudson.util.Secret.decrypt("{HASHxxxxx=}"))
# or /////
println(hudson.util.Secret.fromString("{HASHxxxxx=}").getPlainText())

Trigger build by url

# Run when the anonymous user has the build permission
curl http://127.0.0.1:8080/job/Trigger_Remote_Demo/build?token=My-token
# Send request with credentials
curl -u username:api_token http://127.0.0.1:8080/job/Trigger_Remote_Demo/build
# Build with Parameter
curl -u username:api_token http://127.0.0.1:8080/job/Trigger_Remote_Demo/buildWithParameters?para1=val1&para2=val2

Service Provided in a Lazy Loaded Module

· One min read

Open in Notion

https://angular.io/guide/ngmodule-faq#why-is-a-service-provided-in-a-lazy-loaded-module-visible-only-to-that-module

Unlike providers of the modules loaded at launch, providers of lazy-loaded modules are module-scoped.

When the Angular router lazy-loads a module, it creates a new execution context. That context has its own injector, which is a direct child of the application injector.

The router adds the lazy module's providers and the providers of its imported NgModules to this child injector.

These providers are insulated from changes to application providers with the same lookup token. When the router creates a component within the lazy-loaded context, Angular prefers service instances created from these providers to the service instances of the application root injector.

Jenkins

· 3 min read

Open in Notion

Start Jenkins

Startup script to set the System Properties

Step 1:

  • Locate the Jenkins home directory. You can look into the existing system properties for ‘jenkins_home’ or execute ‘echo $JENKINS_HOME’ inside the jenkins server to get the Jenkins home directory.
  • Say if your Jenkins home directory is ‘/var/jenkins_home’. Create a new directory with name ‘init.groovy.d’.

Step 2:

  • Now change your working directory to ‘/var/jenkins_home/init.groovy.d
  • Within init.groovy.d directory create a new groovy script. Say ‘startup-properties.groovy’

Step 3:

  • Copy the below content to the ‘startup-properties.groovy’ file
import jenkins.model.Jenkins
import java.util.logging.LogManager

/* Jenkins home directory */
def jenkinsHome = Jenkins.instance.getRootDir().absolutePath
def logger = LogManager.getLogManager().getLogger("")

/* Replace the Key and value with the values you want to set.*/
/* System.setProperty(key, value)*/
System.setProperty("hudson.model.WorkspaceCleanupThread.disabled", "true")
logger.info("Jenkins Startup Script: Successfully updated the system properties. Script location: ${jenkinsHome}/init.groovy.d")

Visit https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/System.html?is-external=true#setProperty(java.lang.String,java.lang.String) to see how to use setProperty.

Step 4:

Restart the Jenkins server, you can manually restart the server using :

<Jenkins-server-URL>/restart or <Jenkins-server-URL>/safeRestart

  • Use safeRestart when you have some job still running. It will wait till all the jobs are completed.

Step 5:

Check the logs after Jenkins restart: Manage Jenkins → System Log. You can see while server is starting, its executing the startup-properties.groovy script which is inside init.groovy.d directory.

1*kjzZCxTixWCYsQbIcfRkzA.png

For example, run the below scripts in Script Console to check the System Properties, you will see the required key and values.

println(System.getProperty("hudson.model.WorkspaceCleanupThread.disabled"))

Now every time server is restarted the script will run and set the system properties for you. You don’t need to worry for setting these system properties manually every time server restart.

https://wiki.jenkins-ci.org/display/JENKINS/Features-controlled-by-system-properties.html

Start docker container with system properties

link_preview

docker run --name my-jenkins -p 8080:8080 -p 50000:50000 -v /your/jenkins_home:/var/jenkins_home \
-d \
-v /var/run/docker.sock:/var/run/docker.sock \
--env JAVA_OPTS="-Dhudson.model.WorkspaceCleanupThread.disabled=\"true\"" \
--restart unless-stopped \
--user root \
bndynet/jenkins

Plugin: Configuration as Code (aka.JCasC )

Apply configuration from Git

https://<USERNAME>:<PERSON_ACCESS_TOKEN>@github.com/your-repo/jenkins-config.git

Add Nodes

Step 1. In node server, install java by https://sdkman.io/

curl -s "https://get.sdkman.io" | bash
sdk install java 17.0.14-tem

Step 2. Add java path for all users (/etc/environment)

JAVA_HOME=/home/<user>/.sdkman/candidates/java/current
PATH="/home/<user>/.sdkman/candidates/java/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"

Step 3. Generate ssh key in jenkins server, if you are running jenkins on container, you should enter the container to do that.

ssh-keygen -t rsa -b 4096 -f /var/jenkins_home/id_rsa

Step 4. Copy pub key to node server

ssh-copy-id -i /var/jenkins_home/.ssh/id_rsa.pub username@hostname

Step 5. Add Credentials in jenkins UI with the private key

Step 6. Add Node in jenkins UI with Launch agens via SSH, and choose above Credentials

Q: Could not copy remoting.jar into '/home/jenkins' on agent

If below error thrown:

Permission denied (SSH_FX_PERMISSION_DENIED: The user does not have sufficient permissions to perform the operation.)