Monday, November 11, 2024

APC UPS 1200VA connected to linux debian

On 1st November 2023 was one of the worst ever day in my working life. One super strongest ever lightning strike completely shut off the the whole house electric supply! I have UPS connected to my laptop which the laptop also shut off abruptly. I would say "lucky" ? that that the laptop managed to boot up unfortunately the USBs are all broken, it does not function anymore. Never in my life would think that even with a laptop protected by an APC UPS, the device would be damage, well partially. Closer inspection show that laptop power adapter socket, the live connector got burned mark. It is just how strong was the lightning strike! So lesson learn, this time I bought a new APC UPS which connected in serial fashion and behind a surge protector (Targus) and hoping that with 2x protections, I will survive in the incoming lightning storm. hopefully. 🤞🙏

Let's see the APC UPS






and when it is connected and running



This unit come with monitoring system. It can be connected to the pc device via USB cable which is awesome! Best part is, if you are using linux, it comes detected automagically. At the time of this writing, I'm using Debian 12.7. 

what you need to do is just installed package apcupsd

$ sudo apt install apcupsd
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  hunspell-gl-es hunspell-sv-se libnvidia-compiler libu2f-udev libwpe-1.0-1 libwpebackend-fdo-1.0-1 linux-headers-6.1.0-17-common
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  apcupsd-doc libusb-0.1-4
Suggested packages:
  apcupsd-cgi
The following NEW packages will be installed:
  apcupsd apcupsd-doc libusb-0.1-4
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 670 kB of archives.
After this operation, 1,779 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://deb.debian.org/debian bookworm/main amd64 libusb-0.1-4 amd64 2:0.1.12-32 [23.4 kB]
Get:2 http://deb.debian.org/debian bookworm/main amd64 apcupsd amd64 3.14.14-3.1+b1 [256 kB]
Get:3 http://deb.debian.org/debian bookworm/main amd64 apcupsd-doc all 3.14.14-3.1 [390 kB]
Fetched 670 kB in 0s (3,160 kB/s)    
Selecting previously unselected package libusb-0.1-4:amd64.
(Reading database ... 438864 files and directories currently installed.)
Preparing to unpack .../libusb-0.1-4_2%3a0.1.12-32_amd64.deb ...
Unpacking libusb-0.1-4:amd64 (2:0.1.12-32) ...
Selecting previously unselected package apcupsd.
Preparing to unpack .../apcupsd_3.14.14-3.1+b1_amd64.deb ...
Unpacking apcupsd (3.14.14-3.1+b1) ...
Selecting previously unselected package apcupsd-doc.
Preparing to unpack .../apcupsd-doc_3.14.14-3.1_all.deb ...
Unpacking apcupsd-doc (3.14.14-3.1) ...
Setting up libusb-0.1-4:amd64 (2:0.1.12-32) ...
Setting up apcupsd-doc (3.14.14-3.1) ...
Setting up apcupsd (3.14.14-3.1+b1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/apcupsd.service → /lib/systemd/system/apcupsd.service.
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for libc-bin (2.36-9+deb12u7) ...
Scanning processes...                                                                                                                                                                         
Scanning processor microcode...                                                                                                                                                               
Scanning linux images...                                                                                                                                                                      

Running kernel seems to be up-to-date.

The processor microcode seems to be up-to-date.

No services need to be restarted.

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.

and then start it.

$ sudo systemctl start apcupsd
$ sudo systemctl status apcupsd
● apcupsd.service - UPS power management daemon
     Loaded: loaded (/lib/systemd/system/apcupsd.service; enabled; preset: enabled)
     Active: active (running) since Mon 2024-11-11 21:32:23 +08; 2s ago
       Docs: man:apcupsd(8)
    Process: 212186 ExecStartPre=/lib/apcupsd/prestart (code=exited, status=0/SUCCESS)
    Process: 212190 ExecStart=/sbin/apcupsd (code=exited, status=0/SUCCESS)
   Main PID: 212191 (apcupsd)
      Tasks: 3 (limit: 37451)
     Memory: 584.0K
        CPU: 8ms
     CGroup: /system.slice/apcupsd.service
             └─212191 /sbin/apcupsd

Nov 11 21:32:23 debby systemd[1]: Starting apcupsd.service - UPS power management daemon...
Nov 11 21:32:23 debby systemd[1]: apcupsd.service: Can't open PID file /run/apcupsd.pid (yet?) after start: No such file or directory
Nov 11 21:32:23 debby apcupsd[212191]: apcupsd 3.14.14 (31 May 2016) debian startup succeeded
Nov 11 21:32:23 debby apcupsd[212191]: NIS server startup succeeded
Nov 11 21:32:23 debby systemd[1]: Started apcupsd.service - UPS power management daemon.

and even better, gnome automatically detect it. I was really impress how little effort require to make things work.



one thing it does not work out of the box is communication with UPS also lost... but not sure how gnome able to detect the battery percentage..anyway, guess this is the work require.

$ sudo apcaccess

APC      : 001,018,0437

DATE     : 2024-11-11 21:33:20 +0800  

HOSTNAME : debby

VERSION  : 3.14.14 (31 May 2016) debian

UPSNAME  : debby

CABLE    : USB Cable

DRIVER   : USB UPS Driver

UPSMODE  : Stand Alone

STARTTIME: 2024-11-11 21:32:23 +0800  

STATUS   : COMMLOST 

MBATTCHG : 5 Percent

MINTIMEL : 3 Minutes

MAXTIME  : 0 Seconds

NUMXFERS : 0

TONBATT  : 0 Seconds

CUMONBATT: 0 Seconds

XOFFBATT : N/A

STATFLAG : 0x05000100

END APC  : 2024-11-11 21:33:20 +0800  

In any case, I really like this unit come with monitoring system. I guess just need to find out how to fix the communication problem and it would be a blast!


Reference:

https://opensource.com/article/21/12/linux-apcupsd

https://wiki.debian.org/apcupsd

 

Sunday, June 2, 2024

my code is your code

 If tomorrow is debug day (Type "function")

And I'm standin' with the front-end design

And the lead asks me what I did with my code

I will say I coded with you


If I wake up in Code War III (Code War III)

I see bugs and vulnerabilities

And I feel like I want to go home

It's okay if you're debugging with me


(

Cuz your code is my code

My code is your code

It would take an infinity loop to break us

And the chains of GitHub couldn't fork us

) x2


If I lose my fame and followers (Really don't matter)

And my server crashes down (Really don't matter)

As long as I got your commits (Really don't matter)

It really don't matter (Really don't matter)


As the versions they pass us by (the versions, the versions, the versions, the versions, the versions)

We stay updated through each other's code (each other's code)

And no matter how many updates we make

It's okay as long as I got your merge



(

Cuz your code is my code

My code is your code

It would take an infinity loop to break us

And the chains of GitHub couldn't fork us

) x2


If my code should break today (Break today)

Don't worry, 'cause in code we iterate anyway (Oh no)

"No matter the chatter from others (truly inconsequential)

I'll stand by, awaiting you beyond the reckoning's sway"


(

Cuz your code is my code

My code is your code

It would take an infinity loop to break us

And the chains of GitHub couldn't fork us

) x2

Saturday, May 20, 2023

Now I know why zoom feature is available in operating system for.

I use to think why would an O/S feature is created as it sudden zoom ridiculous 10-100x of the current resolution. 

But as one age, it FINALLY make sense, all comes around! Let's give an example. Given the current view at current resolution of the following picture

Given the following webshot, what's the difference can you identify?



Sure, some with very good eye can spot but it would also take sometime to identify. But if you can zoom in, wouldn't that be nice?! In linux , try super + alt + 8, yes the 8 is not on the numpad. Now it should be clearly shown what is the difference.


The display might be too small, try open the image in a new window tab. It should be clearly seen that the vertical line is dashed whilst the horizontal line is dotted. Well that's the difference!

It is like the zoom feature allow one to inspect the DNA.. well, computer DNA.. :) 


Tuesday, March 7, 2023

how to setup mariadb galera cluster in docker container

 1. create network (one time)

   docker network create --subnet=172.18.0.0/16 mynet123


2. create image that can start service in container (one time)

   mkdir systemd

   cd systemd

   vim Dockerfile

   FROM almalinux

   ENV container docker


   RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in ; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done);


   RUN rm -rf /lib/systemd/system/multi-user.target.wants/ \

   && rm -rf /etc/systemd/system/.wants/ \

   && rm -rf /lib/systemd/system/local-fs.target.wants/ \

   && rm -f /lib/systemd/system/sockets.target.wants/udev \

   && rm -f /lib/systemd/system/sockets.target.wants/initctl \

   && rm -rf /lib/systemd/system/basic.target.wants/ \

   && rm -f /lib/systemd/system/anaconda.target.wants/*


   VOLUME [ “/sys/fs/cgroup” ]

   CMD ["/usr/sbin/init"]


3. build image (one time)

   docker build -t almalinux-md .


4. start the container in the background

   docker run -v /tmp/node1/:/var/lib/mysql --detach --rm -it --privileged --net mynet123 --ip 172.18.0.11 --name node1  almalinux-md 

   docker run -v /tmp/node2/:/var/lib/mysql --detach --rm -it --privileged --net mynet123 --ip 172.18.0.12 --name node2  almalinux-md

   docker run -v /tmp/node3/:/var/lib/mysql --detach --rm -it --privileged --net mynet123 --ip 172.18.0.13 --name node3  almalinux-md  


5. attach it and so can install mariadb and gelera, etc

   docker exec -it node1 bash

   docker exec -it node2 bash

   docker exec -it node3 bash


6. install in all 3 nodes

   dnf install -y mariadb-server.x86_64  mariadb.x86_64 rsync python3-policycoreutils vim nc telnet epel-release.noarch mariadb-server-galera.x86_64


7. on first node

   systemctl start mariadb

   systemctl status mariadb

   [root@6c3d7f5bc394 /]# mysql -uroot

   MariaDB [(none)]> set password = password("password");

   quit;

   systemctl stop mariadb

      

8. from step 5. wsrep_node_address and wsrep_node_name update to its corresponding name   


   [root@cfeee129fe92 /]# cat /etc/my.cnf.d/galera.cnf

   [mysqld]

   binlog_format=ROW

   default-storage-engine=innodb

   innodb_autoinc_lock_mode=2

   bind-address=0.0.0.0


   # Galera Provider Configuration

   wsrep_on=ON

   wsrep_provider=/usr/lib64/galera/libgalera_smm.so


   # Galera Cluster Configuration

   wsrep_cluster_name="ot_mariadb_cluster"

   wsrep_cluster_address="gcomm://172.18.0.11,172.18.0.12,172.18.0.13"


   # Galera Synchronization Configuration

   wsrep_sst_method=rsync


   # Galera Node Configuration

   wsrep_node_address="172.18.0.13"

   wsrep_node_name="node3"

   [root@cfeee129fe92 /]# 


9.  on first node, start the cluster

    galera_new_cluster

   

10. check on the first node,

    mysql -u root -ppassword -e "SHOW STATUS LIKE 'wsrep_cluster_size'"   

   

11. bring up the remaining nodes one by one

    systemctl start mariadb

    mysql -u root -ppassword -e "SHOW STATUS LIKE 'wsrep_cluster_size'"   


12. ready to write/read

mysql -u root -ppassword -e 'CREATE DATABASE playground;

CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));

INSERT INTO playground.equipment (type, quant, color) VALUES ("slide", 2, "blue");'


mysql -u root -ppassword -e 'SELECT * FROM playground.equipment;'

Thursday, February 24, 2022

Best place I think docker container is for

 docker container has been with us for many years. For software engineer which deal with legacy application, it can be intimidating to migrate to docker application. Because system stability, production investigation and quick fix and service stability surpasses every technology stack. At least that is for me, this cannot be compromise. 


So where is docker container is best for? Where do we start docker container for? For many people, if you google, they build the application into docker image and deploy. Sure, that can be done but for me, as a start, I think for learning purposes and best use cases. Here, I would like share my experience and best use cases.


code compiling

Many of us do code compiling and this is especially true if you want to deploy a bunch of application, modify here and there, build the binary , get the final result and then move on. Installing software packages into container will not taint the host. Modify the configuration also need not worry about taint the host. What is even more merrier, you don't have to clean up after you done compiling. One can just delete the container and start over. Guaranteed reproducible end result. This is similar to chroot but container allow you to do further with different o/s.


application on legacy database

sometime when we migrate development server to the latest o/s but however it break the legacy application or its dependency, example database. In such a case, docker can come to the rescue, you can install legacy database in the docker container whilst the application still can access the database without any puzzle or not expected result. This is even more true when you are busy and focus on upgrading the development server, you don't have the time to upgrade the application or its database. When you are done develop development server, you can then upgrade the database to another version inside docker. I think docker in this case is a really good fit.


quick test for code

Many times when you write bash script, you want to quickly test if the script works fine. But you don't want to test run on your machine as it will change the underlying configuration/state. If you run a container, those code can be quickly test it and when you are done, you can exit the container and nothing harmful done to the host. In this case, you are totally sure your code is tested well and in the same time with less maintenance after tests.


That's it I want to share my opinions and use cases for docker container. If I learn new way of using docker, I will update this document. I hope you will find it useful for your use cases.



Friday, June 25, 2021

How to cherry pick on a commit but only a few files from upstream patch

I forked a repository from upstream and there was a patch I like and I would like that patch goes into my forked repository. But at the same time, I would like to pick only a few changes, that is, not the whole commit and at the same time too, I need to make some minor modifications. So here goes how this is done.

Let's check where we are at now.

 jason@localhost:~/advanced-policy-firewall$ git branch  
 * master  
  rfxn_upstream  
  robertoberto-patch  
  support-ipv6  

Get the commit id from roberto patch, cherry pick the whole commit but do not commit yet.. just stage at the current branch (which is master)

 jason@localhost:~/advanced-policy-firewall$ git cherry-pick -n 0d1df6549820f9592aefb2353b77c52eadbe759f  
 Auto-merging files/vnet/vnetgen  
 CONFLICT (content): Merge conflict in files/vnet/vnetgen  
 error: could not apply 0d1df65... - fixed vnetgen for newer linux distros to prioritize ip over ipconfig  
 hint: after resolving the conflicts, mark the corrected paths  
 hint: with 'git add <paths>' or 'git rm <paths>'  
 jason@localhost:~/advanced-policy-firewall$ git status .  
 On branch master  
 Your branch is up to date with 'origin/master'.  
 Changes to be committed:  
  (use "git restore --staged <file>..." to unstage)  
      modified:  README  
      new file:  test/distros_examples/ifconfig_ubuntu_12  
      new file:  test/distros_examples/ifconfig_ubuntu_20  
      new file:  test/distros_examples/ip_addr_ubuntu_12  
      new file:  test/distros_examples/ip_addr_ubuntu_20  
      new file:  test/distros_examples/ip_link_ubuntu_12  
      new file:  test/distros_examples/ip_link_ubuntu_20  
 Unmerged paths:  
  (use "git restore --staged <file>..." to unstage)  
  (use "git add <file>..." to mark resolution)  
      both modified:  files/vnet/vnetgen  

Let's get the diff of the stage file

 jason@localhost:~/advanced-policy-firewall$ git diff --cached README  
 diff --git a/README b/README  
 index 07ad004..0adf39d 100644  
 --- a/README  
 +++ b/README  
 @@ -199,7 +199,7 @@ Fedora Core Any  
  Slackware 8.0+  
  Debian GNU/Linux 3.0+  
  Suse Linux 8.1+  
 -Unbuntu Any  
 +Ubuntu Any  
  TurboLinux Server 9+  
  TurboLinux Fuji (Desktop)  
  RedHat Linux 7.3,8,9  

Unstage a file because I wanna make minor modification. After changes are make, add it back to the stage

 $ git restore --staged test/distros_examples/ip_link_ubuntu_12  
 $ vim test/distros_examples/ip_link_ubuntu_12  
 $ git add test/distros_examples/ip_link_ubuntu_12  

All good now, let's commit

 $ git commit -m "cherry pick but only selected files from roberto patched"  
 [master 80830c9] cherry pick but only selected files from roberto patched  
  8 files changed, 330 insertions(+), 28 deletions(-)  
  create mode 100644 test/distros_examples/ifconfig_ubuntu_12  
  create mode 100644 test/distros_examples/ifconfig_ubuntu_20  
  create mode 100644 test/distros_examples/ip_addr_ubuntu_12  
  create mode 100644 test/distros_examples/ip_addr_ubuntu_20  
  create mode 100644 test/distros_examples/ip_link_ubuntu_12  
  create mode 100644 test/distros_examples/ip_link_ubuntu_20  
 $ git branch  
 * master  
  rfxn_upstream  
  robertoberto-patch  
  support-ipv6  

and we push the changes to github

 $ git push  
 Enumerating objects: 19, done.  
 Counting objects: 100% (19/19), done.  
 Delta compression using up to 16 threads  
 Compressing objects: 100% (13/13), done.  
 Writing objects: 100% (14/14), 3.68 KiB | 3.68 MiB/s, done.  
 Total 14 (delta 7), reused 0 (delta 0), pack-reused 0  
 remote: Resolving deltas: 100% (7/7), completed with 4 local objects.  
 To https://github.com/jasonwee/advanced-policy-firewall.git  
   f98e9bb..80830c9 master -> master  

in case you want to see the final result, please visit this github commit.

Monday, June 21, 2021

Continuous Integration with GitHub Action

This is a contribution to the SUSE Cloud Native Foundations Scholarship Program which I received and some of the peers want a CI online demo. So here I will share on my knowledge and experience on continuous integration using a public repository and public runner. I will start with a sample project creation, GitHub project setup and end with GitHub action setup and runner. 


What is CI? 

In software engineering, continuous integration (CI) is the practice of merging  all developers' working copies to a shared mainline several times a day.[1]


So essentially, it is a routine where every developer has to go through after they made code changes. Example, syntax check, linting, code compiling, multiple tests, package building, perhaps also support different runtime versions and/or operating systems.

There are many CI software available, please choose the one which match your requirements. I particularly like Jenkins a lot but Jenkins would require you to setup the runner on your machine. Since the objective of this blog is all public, hence, I picked GitHub action.

Let's begin with initial project setup. Reference if you want to know more.

https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

https://docs.github.com/en/actions/guides/building-and-testing-java-with-maven


```

$ export JAVA_HOME=/usr/lib/jvm/jdk-11.0.5/

$ mvn --version

Apache Maven 3.6.3

Maven home: /usr/share/maven

Java version: 11.0.5, vendor: Oracle Corporation, runtime: /usr/lib/jvm/jdk-11.0.5

Default locale: en_US, platform encoding: UTF-8

OS name: "linux", version: "5.10.0-7-amd64", arch: "amd64", family: "unix"

$ mvn archetype:generate -DgroupId=ch.weetech.app -DartifactId=demo_ci -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

[INFO] Scanning for projects...

[INFO] 

[INFO] ------------------< org.apache.maven:standalone-pom >-------------------

[INFO] Building Maven Stub Project (No POM) 1

[INFO] --------------------------------[ pom ]---------------------------------

...

...

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time:  5.555 s

[INFO] Finished at: 2021-06-20T14:53:50+08:00

[INFO] ------------------------------------------------------------------------

$ cd demo_ci

$ tree .

.

├── pom.xml

└── src

    ├── main

    │   └── java

    │       └── ch

    │           └── weetech

    │               └── app

    │                   └── App.java

    └── test

        └── java

            └── ch

                └── weetech

                    └── app

                        └── AppTest.java


11 directories, 3 files

$ mvn package


[INFO] Scanning for projects...

[INFO] 

[INFO] -----------------------< ch.weetech.app:demo_ci >-----------------------

[INFO] Building demo_ci 1.0-SNAPSHOT

[INFO] --------------------------------[ jar ]---------------------------------

[INFO] 

[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ demo_ci ---

[INFO] Using 'UTF-8' encoding to copy filtered resources.

...

...

...

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time:  2.221 s

[INFO] Finished at: 2021-06-20T14:56:41+08:00

[INFO] ------------------------------------------------------------------------

$ java -cp target/demo_ci-1.0-SNAPSHOT.jar ch.weetech.app.App

Hello World!

```

Once we have the sample project setup, test and compile code locally okay. Then it is time that we initialize git repository locally and push to GitHub. But before  we do of the following, you need to create a new repository on your GitHub.


```

$ mvn clean

[INFO] Scanning for projects...

[INFO] 

[INFO] -----------------------< ch.weetech.app:demo_ci >-----------------------

[INFO] Building demo_ci 1.0-SNAPSHOT

[INFO] --------------------------------[ jar ]---------------------------------

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time:  2.079 s

[INFO] Finished at: 2021-06-20T15:24:46+08:00

[INFO] ------------------------------------------------------------------------

$ git init 

hint: Using 'master' as the name for the initial branch. This default branch name

hint: is subject to change. To configure the initial branch name to use in all

hint: of your new repositories, which will suppress this warning, call:

hint: 

hint: git config --global init.defaultBranch <name>

hint: 

hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and

hint: 'development'. The just-created branch can be renamed via this command:

hint: 

hint: git branch -m <name>

$ git status -m master

$ git status .

On branch master


No commits yet


Untracked files:

  (use "git add <file>..." to include in what will be committed)

pom.xml

src/


nothing added to commit but untracked files present (use "git add" to track)

$ git add pom.xml src/

$ git commit -m "initial"

[master (root-commit) 2cd8641] initial

 3 files changed, 108 insertions(+)

 create mode 100644 pom.xml

 create mode 100644 src/main/java/ch/weetech/app/App.java

 create mode 100644 src/test/java/ch/weetech/app/AppTest.java

$ git remote add origin https://github.com/jasonwee/demo_ci.git

$ git branch -M main

$ git push -u origin main

Enumerating objects: 16, done.

Counting objects: 100% (16/16), done.

Delta compression using up to 16 threads

Compressing objects: 100% (6/6), done.

Writing objects: 100% (16/16), 1.76 KiB | 899.00 KiB/s, done.

Total 16 (delta 0), reused 0 (delta 0), pack-reused 0

To https://github.com/jasonwee/demo_ci.git

 * [new branch]      main -> main

Branch 'main' set up to track remote branch 'main' from 'origin'.

$ git status .

On branch main

Your branch is up to date with 'origin/main'.


nothing to commit, working tree clean


```

Now that you pushed everything to GitHub, next is to setup GitHub Actions.

1. Locate Actions from the project tab.

2. Picked 'Java with Maven' as this best match the current requirement.

3. Check action configurations are okay and commit it. 



4. once you commit, the action will kickstart the first run.


Congratulation! This is the first CI that you setup. The rest, as you may have already guessed will be the same as every developer will do, i.e. making code changes.

```

$ vim README.md

$ cat README.md

a contribution to https://www.udacity.com/scholarships/suse-cloud-native-foundations-scholarship

$ git status .

On branch main

Your branch is up to date with 'origin/main'.


Untracked files:

  (use "git add <file>..." to include in what will be committed)

README.md


nothing added to commit but untracked files present (use "git add" to track)

$ git add README.md 

$ git commit -m "added readme" README.md 

[main a966f09] added readme

 1 file changed, 1 insertion(+)

 create mode 100644 README.md

$ git push

Enumerating objects: 4, done.

Counting objects: 100% (4/4), done.

Delta compression using up to 16 threads

Compressing objects: 100% (3/3), done.

Writing objects: 100% (3/3), 410 bytes | 410.00 KiB/s, done.

Total 3 (delta 0), reused 0 (delta 0), pack-reused 0

To https://github.com/jasonwee/demo_ci.git

   a273126..a966f09  main -> main

```





That's it, in case you figure where can I find this repository to begin mine? https://github.com/jasonwee/demo_ci