顯示指令執行進度-pv

在進行備份或者是複製大檔的時候,通常會想知道進度,但這通常需要指令本身有處理這塊,例如 rsync,否則一般是沒進度的。

那麼,有方法可以做到這件事情嗎?有的,就是使用 pv 這個指令。

安裝

安裝 pv 很簡單,在 Debian/Ubuntu 裡,用 apt 就可以安裝。

sudo apt install pv

在 RHEL/CentOS 裡,需要加入 EPEL 這個 repository (安裝方法sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm )

再使用 yum 安裝即可

sudo yum install pv

使用

看了參考資料的文章以後,我個人的理解是這樣子的,第一種使用方法,是把檔案當作參數,pv 會讀取檔案,然後輸出到 stdout,pv 就是依照檔案的長度來做進度顯示。直接來看看幾個例子

例1:複製大檔

pv big-file > /tmp/big-file

例2:壓縮大檔

pv big-file | bzip2 > /tmp/big-file.bz2

例3:用 tar 來備份,這邊的 -p –timer –rate –bytes 是因應不知道檔案大小所加上去的設定,這邊也可以看到 pv 可以接收 stdin 的資料,顯示進度,然後再寫到 stdout。

tar -czf - ./Downloads/ | (pv -p --timer --rate --bytes > backup.tgz)

例4:同時看多個處理動作的狀況

pv -cN raw file | gzip | pv -cN gzip > file.gz

例5:備份跟還原整顆磁碟

pv -EE /dev/sda > disk-image.img
pv disk-image.img > /dev/sda

例6:複製目錄

rsync -avr --progress Downloads /mnt

等等,不是說好用 pv 嗎?對,你沒看錯,用 rsync,不要用 pv 去串了,這樣比較清楚。

參考資料

在MacOS使用其他版本的java

在 Linux 裡要切換 java,可以使用 update-alternative --config java

在 MacOS 裡,要用 /usr/libexec/java_home

MacOS 本身就有帶一包 java ,是 OpenJDK,所以在要切換之前,得先說一下,怎麼安裝其他版本的 java 。要安裝其他版本的 java,用 homebrew 的話,是很簡單的。

要安裝 oracle-jdk,就用

brew search oracle-jdk

要安裝 adoptopenjdk,就用

brew tap adoptopenjdk/openjdk
brew install adoptopenjdk8

要知道裝了哪些 jdk,可以用

/usr/libexec/java_home -V

這行指令會列出所有安裝的 Java ,從這邊可以取得版本號碼跟名稱。

知道版本以後,要使用指定版本的 Java ,可以用切換 PATH 的方式來處理

export JAVA_HOME=$(/usr/lib_exec/java_home -v <your_java_version>)
export PATH=${JAVA_HOME}/bin:${PATH}

參考資料

pip-audit

github 會針對套件去做安全檢核並發出通知或是 pull request,如果本地端想要做這件事,該怎麼做呢?

剛好前幾天看到這篇:How to find third-party vulnerabilities in your Python code ,文章裡就介紹了 pip-audit 這個工具。使用這個工具,就可以對使用的套件來做安全檢核,並給予建議。

安裝方法很簡單,用 pip 安裝就可以

pip install --upgrade pip-audit pip

安裝完成後,就可以使用 pip-audit 指令了。

要對使用的套件檢查,可以用

pip-audit -r requirements.txt

檢查需要花一段時間,檢查後的結果大致會類似這樣子:

Found 1 known vulnerability in 1 package                                              
Name    Version ID             Fix Versions
------- ------- -------------- ------------
urllib3 1.25.11 PYSEC-2021-108 1.26.5

你會看到有幾個已知漏洞,套件的名稱跟修正的版本。

若要即時的修正,pip-audit 也可以做修正。

pip-audit --fix

要注意的是,這個修正只是幫你安裝已經沒有漏洞的版本,requirements.txt 裡還是要自己去修正。

後續思考:

  1. 可以在 CI 流程裡使用 pip-audit 來做安全檢核,避免使用到有漏洞的版本。
  2. 使用 poetry 的話,可以把 pip-audit 列為 dev dependencies ,就不需要在正式環境裡也裝上這工具了。

Python inspect

之前在用 c# 時,可以使用 reflection 來查找類別可以使用的方法或屬性,甚至是函式庫裡有什麼類別、函式可以使用。在 Python 可以用 inspect 模組來達成這件事情:How to list all functions in a Python module?

例如要列出模組裡所有的函式,可以這樣用:

from inspect import getmembers, isfunction
from somemodule import foo

print(getmembers(foo, isfunction))

或是要找出名字裡有 castle 的成員,像是函式、類別等等的:

import inspect
import example

for name, data in inspect.getmembers(example):
    if 'castle' not in name:
        continue
    print('{} : {!r}'.format(name, data))

或是要找類別名稱是 XXXManager 的類別:

import inspect
import example

for name, data in inspect.getmembers(example, inspect.isclass):
    if name.endswith('Manager'):
      print('{} : {!r}'.format(name, data))

要撈 docstring 也可以,更多的用法可以參考 PyMOTW: inspect — Inspect Live Objects

Python 網站上的文件:inspect – Inspect Live Objects

Registry Mirror

最近在建置 container image 時,常會踩到 exceeded 的錯誤,這是因為 docker 在 2020 時,公告了新的收費機制,並為拉取 container image 的 API 加上了限制,沒有登入的使用者現在每6個小時只能有 100 個 pull requests可用;有登入且採用免費方案的使用者,每6個小時有 200 個 pull requests 可用。這在初期測試 pipeline 時,根本很容易就用超過。

上網搜尋看有沒有方法可以避過這限制,後來在 gitlab 網站上找到文章:Caching Docker images to reduce the number of calls to DockerHub from your CI/CD infrastructure | GitLab

文章裡有提到兩個方法,第一個簡單的方法就是登入,這樣可以提升到 200 個 pull requests。

因為大部分的 executor 都是使用 docker 或 docker + machine,所以設定方法可以單純的在 pipeline 裏面作 docker login,但這樣還要多塞指令跟 credential 。gitlab 很貼心的提供了一個內建的變數,要用這個變數,需要在 gitlab 專案的 settings > CI/CD > Variables 裡,去增加 DOCKER_AUTH_CONFIG ,那在執行 pipeline 時,gitlab-runner 看到有這個變數,就會自動做 login 的動作。

DOCKER_AUTH_CONFIG 的內容可以透過以下方式取得:

  1. 在終端機用指令先登入 index.docker.io: docker login
  2. 用 docker 指令登入後,在家目錄的 .docker 目錄下就會出現 config.json : cat ~/.docker/config.json
  3. 用 jq 指令讓內容變成一行: jq -c "." ~/.docker/config.json

輸出的結果,就可以拿來填了。

第二個方法,則是建置 Registry mirror。

找一台已經安裝 docker 的主機,然後使用 docker 啟動 registry container。在啟動的時候帶入環境參數 REGISTRY_PROXY_REMOTEURL

docker run -d -p 6000:5000 \
    -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \
    --restart always \
    --name registry registry:2

然後登入到 gitlab-runner 所在的主機,修改 /etc/docker/daemon.json ,內容如下

{
  "registry-mirrors": ["http://<your-registry-mirror-server:6000"]
}

修改完以後,讓 dockerd 重新載入設定:

sudo systemctl reload docker

再用 docker info | grep -A 1 -B 1 Mirror 確認。

這樣就設定完成了。

那要怎麼知道 gitlab-runner 在建置時有使用這個 registry mirror 呢?這時可以用 curl 指令來檢查

watch -n 60 curl -s http://<your-registry-server>:6000/v2/_catalog

輸出結果大致會是這樣

{"repositories":["library/docker","library/python"]}

至此,就可以算是解決了 exceeded 的問題啦。