---
# System prepended metadata

title: '[Account] user / 建立 user 的正確流程應為何？'
tags: [Association, Partition, Slurm, Linux, User, Slurm / Account, Slinky, SlinkyProject, QOS, Account, HPC]

---

[Account] user / 建立 user 的正確流程應為何？
===
###### tags: `Slurm / Account`
###### tags: `Slurm`, `HPC`, `Linux`, `Slinky`, `SlinkyProject`, `Account`, `User`,  `Association`, `Partition`, `QOS`

<br>

[TOC]

<br>

## 🎯 標準教學範例
> 本教學範例示範如何**正確建立 Slurm 使用者**。整體原則是：
> 1. **先建立作業系統(OS)帳號**
> 2. **再建立 Slurm 帳務(Accounts / Users / Associations)**
> 3. **驗證**
> 4. **送出最小測試作業**

---

### ✅ 目標

為新成員建立：

* 同步一致的 **OS 帳號**（所有可執行作業的節點都能辨識同一個 UID / GID）
* 對應的 **Slurm 帳務**（Account / User / Partition / QOS 等關聯）
* 完成驗證與最小作業測試

---

### 🧰 事前約定（請自行替換）

為了教學清晰，先定義一組教學變數（你可以直接複製，或改成你的實際名稱）：

```bash
# === 你可以在 shell 先 export 這些變數，後面指令直接貼上使用 ===
export CLUSTER="slurm1"           # Slurm 叢集名稱
export ACCOUNT="cloud-team"       # Slurm 帳務 Account 名稱
export ORG="cloud-org"            # Account 所屬組織(備註用，可自訂)
export GROUP="$ACCOUNT"           # 建議 Linux 群組同名，便於管理
export USERNAME="alice"           # 新使用者帳號
export UID_NUM="20001"            # 固定 UID，確保各節點一致
export GID_NUM="20001"            # 固定 GID（可用同一值或依實際規劃）
export SHELL="/bin/bash"
export HOME_DIR="/home/$USERNAME"
export PARTITIONS=("debug" "tn")  # 允許使用的 partition 清單
export QOS_NAME="normal"          # 允許的 QOS (Quality of Service)
```

---

### ① 建立 **作業系統** 帳號（先做這步，最重要）

> Slurm 最終會以使用者的 **UID/GID** 執行作業；若計算節點找不到該 UID，作業派發會失敗。

在所有需要「提交/執行」的環境（login 節點與所有 compute 節點）確保能辨識到相同的 UID/GID。常見做法：

* **集中式**：LDAP/SSSD（建議）
* **本地同步**：在每個節點建立相同的帳號與群組
* **家目錄**：用 NFS 或共享儲存，確保同一路徑（例如 `/home/alice`）

範例（Debian/Ubuntu 類）：
（已存在就跳過對應指令）

```bash
# 1) 新增群組（同名方便對應 Slurm Account）
sudo groupadd -g "$GID_NUM" "$GROUP"

# 2) 新增使用者（固定 UID/GID；建立家目錄）
sudo useradd -m -u "$UID_NUM" -g "$GROUP" -s "$SHELL" -d "$HOME_DIR" "$USERNAME"
sudo passwd "$USERNAME"

# 3) 驗證（在每台需要的節點都要能通過）
getent passwd "$USERNAME"
id "$USERNAME"
ls -ld "$HOME_DIR"
```
- **執行結果**
    ```
    $ getent passwd "$USERNAME"
    alice:x:20001:20001::/home/alice:/bin/bash

    $ id "$USERNAME"
    uid=20001(alice) gid=20001(cloud-team) groups=20001(cloud-team)

    $ ls -ld "$HOME_DIR"
    drwxr-x--- 2 alice cloud-team 4096 Aug 28 09:13 /home/alice
    ```
> **Tips**:
> - 若用 LDAP/SSSD，請在目錄服務中建立相同的使用者與群組；
> - 節點端僅需驗證 `getent passwd USERNAME` 能解析成功。

<br>

---

### ② 建立 **Slurm 帳務** 與使用者關聯

> 這一步才是 `sacctmgr`，但請務必在 OS 帳號準備妥當後再做。

```bash
# 2-1) 建立/確認 Account
sacctmgr show account name="$ACCOUNT"
# 若沒有，建立一個 Account（Organization 可自訂備註）
sacctmgr create account name="$ACCOUNT" Organization="$ORG" cluster="$CLUSTER"
# 確認 Account
sacctmgr show account name="$ACCOUNT"

# 2-2) 建立 User，指定預設帳戶與叢集
sacctmgr create user name="$USERNAME" DefaultAccount="$ACCOUNT" Cluster="$CLUSTER"
# 確認 User
sacctmgr show user name="$USERNAME"

# 2-3) 加上允許使用的 partition 關聯（可多個；逐一新增）
for p in "${PARTITIONS[@]}"; do
  sacctmgr add user name="$USERNAME" account="$ACCOUNT" cluster="$CLUSTER" partition="$p"
done

# 2-4) 指定/開放 QOS（以下將 QOS 設為單一 normal；若要附加可用 `qos+=`）
sacctmgr modify user name="$USERNAME" set qos="$QOS_NAME"

# 2-5) （選用）資源上限/配額範例
sacctmgr modify user name="$USERNAME" set MaxJobs=10
sacctmgr modify user name="$USERNAME" set MaxSubmitJobs=50
sacctmgr modify user name="$USERNAME" set MaxTRESPerJob=cpu=32,mem=64G
```
- **2-1) account 執行結果**
    ```
    # 簡單的 account 資訊
    $ sacctmgr show account name="$ACCOUNT"
       Account                Descr                  Org 
    ---------- -------------------- -------------------- 
    cloud-team           cloud-team            cloud-org
    ```
    ```
    # 更詳細的 account 資訊
    $ sacctmgr show account name="$ACCOUNT" withassoc 
    $ sacctmgr show account name="$ACCOUNT" withassoc \
        format=account,Descr,Org,Cluster,ParentName,User,QOS
       Account                Descr                  Org    Cluster ParentName       User                  QOS 
    ---------- -------------------- -------------------- ---------- ---------- ---------- -------------------- 
    cloud-team           cloud-team            cloud-org     slurm1       root                          normal 
    cloud-team           cloud-team            cloud-org     slurm1                 alice               normal
    ```
- **2-2) user 執行結果**
    ```
    # 簡單的 user 資訊
    $ sacctmgr show user name="$USERNAME"
          User   Def Acct     Admin 
    ---------- ---------- --------- 
         alice cloud-team      None
    ```
    ```
    # 更詳細的 account 資訊
    $ sacctmgr show user name="$USERNAME" withassoc
    $ sacctmgr show user name="$USERNAME" withassoc \
        format=User,DefaultAccount,Admin,Cluster,Account,Partition,QOS
          User   Def Acct     Admin    Cluster    Account  Partition                  QOS 
    ---------- ---------- --------- ---------- ---------- ---------- -------------------- 
         alice cloud-team      None     slurm1 cloud-team                          normal
    ```
- **2-3) partition 關聯的執行結果**
    ```
    $ sacctmgr show user name="$USERNAME" withassoc \
        format=User,DefaultAccount,Admin,Cluster,Account,Partition,QOS
          User   Def Acct     Admin    Cluster    Account  Partition                  QOS 
    ---------- ---------- --------- ---------- ---------- ---------- -------------------- 
         alice cloud-team      None     slurm1 cloud-team                          normal 
         alice cloud-team      None     slurm1 cloud-team      debug               normal 
         alice cloud-team      None     slurm1 cloud-team         tn               normal 
    ```
- **2-5) 「資源上限/配額」的執行結果**
    ```
    $ sacctmgr show user name="$USERNAME" withassoc
          User   Def Acct     Admin    Cluster    Account  Partition     Share   Priority MaxJobs MaxNodes  MaxCPUs MaxSubmit     MaxWall  MaxCPUMins                  QOS   Def QOS 
    ---------- ---------- --------- ---------- ---------- ---------- --------- ---------- ------- -------- -------- --------- ----------- ----------- -------------------- --------- 
         alice cloud-team      None     slurm1 cloud-team                    1                 10                32        50                                       normal           
         alice cloud-team      None     slurm1 cloud-team      debug         1                 10                32        50                                       normal           
         alice cloud-team      None     slurm1 cloud-team         tn         1                 10                32        50                                       normal
    ```

<br>

---

### ③ 驗證關聯是否正確

```bash
# 簡潔檢視（含關聯）
sacctmgr list user name="$USERNAME" withassoc \
  format=User,DefaultAccount,Cluster,Account,Partition,QOS,MaxJobs,MaxSubmit,MaxTRES
```
- **期待看到**：
    * 使用者 `$USERNAME` 的 `DefaultAccount` = `$ACCOUNT`
    * 有你剛加上的 partitions（例如 debug / tn）
    * `QOS` 包含你設定的 `$QOS_NAME`
    * 上限項目與預期相符
- **執行結果**
    ```
    sacctmgr list user name="$USERNAME" withassoc \
      format=User,DefaultAccount,Cluster,Account,Partition,QOS,MaxJobs,MaxSubmit,MaxTRES
          User   Def Acct    Cluster    Account  Partition                  QOS MaxJobs MaxSubmit       MaxTRES 
    ---------- ---------- ---------- ---------- ---------- -------------------- ------- --------- ------------- 
         alice cloud-team     slurm1 cloud-team                          normal      10        50 cpu=32,mem=6+ 
         alice cloud-team     slurm1 cloud-team      debug               normal      10        50 cpu=32,mem=6+ 
         alice cloud-team     slurm1 cloud-team         tn               normal      10        50 cpu=32,mem=6+
    ```

<br>

---

### ④ 以該使用者送出最小測試作業

在 login 節點（或提交環境）切換成該使用者測試：

```bash
# 切換身份（或用該使用者直接登入）
sudo -iu "$USERNAME"  # 或：su - "$USERNAME"

# 以 srun 做最小測試（請挑一個你剛允許的 partition）
# 注意：新環境，需重新導入環境變數
srun -A "$ACCOUNT" -p "${PARTITIONS[0]}" -N1 -n1 bash -lc 'whoami; id; hostname'

# 或用 sbatch（會產生 .out 檔）
sbatch -A "$ACCOUNT" -p "${PARTITIONS[0]}" -N1 -n1 --wrap='hostname && whoami && id'
```
- **指令說明**
    - **`srun -A "$ACCOUNT" -p "${PARTITIONS[0]}" -N1 -n1 bash -lc 'whoami; id; hostname'`**
        用 `srun` 開一個最小工作步驟，檢查你跑到哪台機器、用誰的身分

        **參數說明**：
        - **`-A "$ACCOUNT"` / `--account`**：
            - 指定要用的 Slurm 帳號（Account）。
            - 決定計費/權限，須與該分區有關聯。
        - **`-p "${PARTITIONS[0]}"` / `--partition`**：
            - 指定要投遞的分區（佇列）。
            - `"${PARTITIONS[0]}"` 是 Bash 陣列 `PARTITIONS` 的第 0 個元素。
        - **`-N1` / `--nodes=1`**：
            - 要求 1 個節點（至少）。
        - **`-n1` / `--ntasks=1`**：
            - 總任務數 1（通常=1 個 MPI rank）。
            - 若要多執行緒，再搭配 `-c <cpus-per-task>`。
        - **`bash -lc '…'`**：
            - 啟動 bash，`-l` 以 login shell 讀取環境設定，`-c` 執行引號內指令。
            - `hostname`：顯示實際執行的節點名稱
            - `whoami`：顯示使用者
            - `id`：顯示 UID/GID 與群組

若執行後：

* `whoami` 顯示 `$USERNAME`
* `id` 顯示你的 UID/GID
* 能成功回傳 `hostname`
  → 即為成功。

> **Tips**:
> - [[HackMD] sbatch 指令除錯](/e3p9okKeRsmqZgvkZ33DWA)
>   - 如何查看 sbatch 的執行結果？
>   - 沒有看到 sbatch 的執行結果？

<br>

---

### 🩹 常見錯誤速查

| 症狀/訊息                                                     | 可能原因                                  | 處理方式                                                                         |
| --------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |
| `There is no uid for user 'xxx'`（或作業派發時出現 user not found） | 計算節點/執行環境無法解析該 OS 帳號（UID/GID 不存在或不一致） | **回到步驟 ①**：在所有需要的節點建立相同 UID/GID，或改用 LDAP/SSSD；確認 `getent passwd USERNAME` 可用 |
| `sbatch`/`srun` 找不到預設帳戶                                   | Slurm DefaultAccount 未設或設錯            | 重新執行 `sacctmgr create/modify user ... DefaultAccount=...`                    |
| 沒看到預期的 partition                                          | 未建立對應的使用者關聯                           | 重新執行 `sacctmgr add user name=... account=... cluster=... partition=...`      |
| QOS 不生效/列表不對                                              | QOS 未掛到使用者                            | `sacctmgr modify user name=... set qos=normal`（或 `qos+=normal` 以附加）          |
| `.out` 檔不出現                                               | 作業快速失敗或輸出目錄權限問題                       | 用 `scontrol show job <jobid>` 看 `Reason`；確認家目錄可寫，或在 `--wrap` 中指定絕對輸出路徑       |

---

### 🧼（可選）清理與重建

若先前建立關聯有誤，建議用「移除關聯 → 重新新增」方式修正（以下僅示意，請小心使用）：

```bash
# 列出關聯後，再選擇性移除（務必先確認）
sacctmgr show assoc user="$USERNAME" cluster="$CLUSTER"
# 例如移除特定 partition 的關聯
sacctmgr delete user name="$USERNAME" account="$ACCOUNT" cluster="$CLUSTER" partition="${PARTITIONS[0]}"
# 需要時再 add 回去
sacctmgr add user name="$USERNAME" account="$ACCOUNT" cluster="$CLUSTER" partition="${PARTITIONS[0]}"
```

---

### 小結

1. **先 OS 帳號**（所有節點能看到相同 UID/GID，家目錄可用）
2. **再 Slurm 帳務**（Account / User / Partition / QOS / 配額）
3. **查驗 withassoc**
4. **最小作業測試**（`whoami; id; hostname`）

照此流程建立，之後新增新成員會穩定且可預期。若你提供目前環境的 partition 與 QOS 命名，我也可以幫你把上面腳本客製成「一鍵建立新使用者」的版本。

<br>

---
---

<br>

## Troubleshooting

### 設定好 account ，卻無法派送 job
- ### 常見原因
    1. **`DeafultAccount` 和 partition 所設定的 `AllowAccounts` 沒有匹配**
        - 透過 `sacctmgr list user withassoc` 可查詢 `DeafultAccount`
    2. **因為 `DeafultAccount` 和 partition 所設定的 `AllowAccounts` 沒有匹配，且 `srun` or `sbatch` 又沒有添加 `-A` (`--acount`) 參數來指定特定 account**
        - 透過 `srun -p debug --acount=<ACCOUNT> hostname` 可指定特定 account 來派送 job
        - 即使 user 是 `root` 或 user 具有 Admin 屬性，`DeafultAccount` 和 partition 所設定的 `AllowAccounts` 沒有匹配的情況下，仍依舊無法派送 job
            錯誤訊息：`srun: error: Unable to allocate resources: Invalid account or account/partition combination specified`
- ### 不明原因 (未能重製，待觀察)
    - ### Case: 設定其他 account 作為 `DeafultAccount`
        ```bash=
        # login node/pod
        sacctmgr list account
        sacctmgr list user

        # 建立使用者 admin2
        useradd admin2 -m -s /bin/bash
        sacctmgr create user name=admin2 account=admin  # 1st account, DefaultAccount=admin
        sacctmgr create user name=admin2 account=tj-account # 2nd account
        sacctmgr list user

        # 變更 defaultaccount
        sacctmgr modify user name=admin2 set defaultaccount=tj-account
        sacctmgr list user withassoc

        # 切換使用者：root -> admin2，執行 srun
        su - admin2
        srun -p debug hostname
        ```

<br>

---

### `error: couldn't chdir to `/home/admin': No such file or directory: going to /tmp instead`
- ### log
    ```
    $ srun -p debug hostname
    [2025-08-29T02:26:46.820] error: couldn't chdir to `/home/admin': No such file or directory: going to /tmp instead
    [2025-08-29T02:26:46.824] error: couldn't chdir to `/home/admin': No such file or directory: going to /tmp instead
    e900-0
    ```
- ### 問題根源
    計算節點沒有 admin 帳號
- ### 解決方式
    在計算節點上，新增 admin 帳號
    ```
    useradd -m -s /bin/bash admin
    ```
- ### 完整解法
    ```bash
    export ACCOUNT="cloud-team"       # Slurm 帳務 Account 名稱
    export GROUP="$ACCOUNT"           # 建議 Linux 群組同名，便於管理
    export USERNAME="admin"           # 新使用者帳號
    export UID_NUM="20000"            # 固定 UID，確保各節點一致
    export GID_NUM="20000"            # 固定 GID（可用同一值或依實際規劃）
    export SHELL="/bin/bash"
    export HOME_DIR="/home/$USERNAME"

    # 1) 新增群組（同名方便對應 Slurm Account）
    sudo groupadd -g "$GID_NUM" "$GROUP"

    # 2) 新增使用者（固定 UID/GID；建立家目錄）
    sudo useradd -m -u "$UID_NUM" -g "$GROUP" -s "$SHELL" -d "$HOME_DIR" "$USERNAME"
    sudo passwd "$USERNAME"

    # 3) 驗證（在計算節點要能通過）
    getent passwd "$USERNAME"
    id "$USERNAME"
    ls -ld "$HOME_DIR"
    ```
    
<br>

---

### `error: couldn't chdir to `/home/admin': Permission denied: going to /tmp instead`
- ### 快速理解
    派送 job 時，會使用登入帳號的 uid (例如測試帳號 admin) ，然後派送到計算節點上執行，於是出現 uid 不一致，導致 Permission denied

- ### 現象（Symptoms）（log）
    執行互動或批次工作時看到：
    ```
    $ srun -p debug hostname
    [2025-08-29T02:29:52.977] error: couldn't chdir to `/home/admin': Permission denied: going to /tmp instead
    [2025-08-29T02:29:52.979] error: couldn't chdir to `/home/admin': Permission denied: going to /tmp instead
    e900-0
    ```
    > Slurm 在啟動工作時會嘗試 `chdir($HOME)`；若家目錄權限/擁有者不一致，就會退回 `/tmp`。

- ### 問題根源（Root Cause）
    - **UID 不一致**：Login 節點與計算節點上，同名使用者（如 `admin`）的 **UID 不同**。
        - **備註**：GID 可不同。GID 不同不影響執行
    - 家目錄（通常是 NFS 或預先建立的本機目錄）在計算節點被視為「別的 UID 擁有」，因此 `chdir` 觸發 `Permission denied`。

- ### 問題觸發流程
    > by gpt-5, reviewed by DeepWiki
    - **提交 (submit)**：使用者在 **login 節點 (submit host)** 透過 `srun` 提交作業；Slurm 會把**提交當下的數字 UID/GID (numeric UID/GID)** 記錄到作業描述中（由 `slurmctld` 持有），**controller 不需要本機使用者條目**。
    - **派送 (dispatch)**：`slurmctld` 排程到目標 **compute 節點** 後，該節點的 `slurmd` 產生 `slurmstepd` 來執行作業。
    - **切換身分 (setuid)**：`slurmstepd` 依作業描述中的 **numeric UID** 執行 `setuid()`／`seteuid()`；此動作**不依賴 controller 的 `/etc/passwd`**，也**不一定需要**本機有相同的使用者名稱（重點是數字 UID）。
        ![image](https://hackmd.io/_uploads/Hyudti0Fge.png)
        ![image](https://hackmd.io/_uploads/rkvnusRFlg.png)
    - **決定與進入工作目錄 (chdir)**：`slurmstepd` 嘗試 `chdir(step->cwd)`（`step->cwd` 來自提交端的工作目錄設定，預設為執行 `srun` 時的當前目錄，可透過 `--chdir` 選項修改）。
        > ![image](https://hackmd.io/_uploads/HylMYiRYxx.png)
        > cite: https://deepwiki.com/search/-log-srun-p-debug-hostname-202_e856b1f9-1502-4ba7-84f6-c465a6dddf6f
    - **權限判定 (permission check)**：檔案系統以 **numeric UID/GID** 判斷權限；若該 compute 節點上 `/home/<user>` 的實際擁有者 UID 與提交端記錄的 UID 不一致，核心回傳 **`EACCES`**。
    - **回退 (fallback)**：Slurm 記錄
      `error: couldn't chdir to '/home/<user>': Permission denied: going to /tmp instead`，並改以 **`/tmp`** 作為工作目錄繼續執行。
      ![image](https://hackmd.io/_uploads/Hyy9_sRFlx.png)

    > 重點：**controller 不需有使用者帳號**；關鍵是 **submit host 與所有會執行作業的 compute 節點** 必須有一致的 **numeric UID**（GID 是否一致則視你的目錄權限設計而定）。


- ### 快速確認（Quick Checks）

    在 **所有節點**（login、compute）比對以下內容：

    ```bash
    # 1) 使用者與群組條目
    getent passwd admin
    getent group admin

    # 2) 目錄擁有者與權限（應該是同一個 UID/GID）
    namei -l /home/admin
    stat -c '%U:%G %a %n' /home/admin

    # 3) NFS 情境下，確認導出與掛載一致（選做）
    mount | grep ' /home '
    ```
    - 若不同節點回傳的 UID/GID 不一致，即為本案。
    - **執行範例**
        ```
        root@slurm-login-6fb5d948d6-5mcvp:~# namei -l /home/admin
        f: /home/admin
        drwxr-xr-x root   root   /
        drwxr-xr-x root   root   home
        drwxr-x--- admin  admin  admin
        
        root@slurm-login-6fb5d948d6-5mcvp:~# stat -c '%U:%G %a %n' /home/admin
        admin:admin 750 /home/admin
        ```
    - **指令解釋**
        - **`namei -l /home/admin`**
            這個指令把路徑逐層「拆解」，列出每一層的**權限 (permissions)**、**擁有者 (owner)**、**群組 (group)** 與**型態 (file type)**，用來找出哪一層目錄造成 `Permission denied`。

            ```bash
            namei -l /home/admin
            ```

            * `namei`：顯示路徑解析 (path resolution)。
            * `-l`：長格式 (long), 類似 `ls -l`，會列出 permissions/owner/group。

            **範例輸出與解讀**：

            ```
            f: /home/admin
            drwxr-xr-x root root /
            drwxr-xr-x root root home
            drwx------ admin admin admin
            ```

            * 每一行代表路徑的一層：`/` → `home` → `admin`
            * 欄位含意：
                * `d/-/l`(directory/regular file/symlink) + `rwx` 權限
                * `owner` 權限
                * `group` 權限
                * 名稱
            * 若有符號連結 (symlink) 會顯示 `l... linkname -> target`

            **小提醒**：

            * 要能 `cd` 進 `/home/admin`，對每一層目錄至少需要 **execute (x) 權限**（又稱 search bit）。缺少任何一層的 `x`，就會出現 `Permission denied`。
        - **`stat -c '%U:%G %a %n' /home/admin`**
            這行指令用 `stat` 依自訂格式顯示 `/home/admin` 的 **擁有者 (owner)**、**群組 (group)**、**權限(permissions)** 與 **名稱/路徑 (filename/pathname)**
            * `-c '...'`: 自訂輸出格式 (custom format)
            * `%U`: 檔案擁有者的使用者名稱 (owner)
            * `%G`: 檔案擁有者的群組名稱 (group)
            * `%a`: 八進位權限 (numeric permissions, octal)（如 700、755）
            * `%n`: 檔名/路徑 (filename/pathname)
- ### 解決方式
    在計算節點上新增 admin 帳號時，需同時指定 login 節點上的 admin 帳號 uid
    ```
    useradd -m -s /bin/bash -u 20000 admin
    ```
    - 參數 `-u 20000` 是關鍵
    - 假設 login 節點上的 admin 帳號 uid 為 20000
    - 查詢方式
        ```
        root@slurm-login-6fb5d948d6-5mcvp:~# id admin
        uid=20000(admin) gid=20000(admin) groups=20000(admin)
        ```
- ### 臨時繞過（如果只想先把作業跑起來）
    ```bash
    srun --chdir=/tmp -p debug hostname
    # 或
    srun -D /tmp -p debug hostname
    ```
    > 僅作權宜之計；正式應 **統一 UID/GID**。
- ### 完整解法
    ```bash
    export ACCOUNT="cloud-team"       # Slurm 帳務 Account 名稱
    export GROUP="$ACCOUNT"           # 建議 Linux 群組同名，便於管理
    export USERNAME="admin"           # 新使用者帳號
    export UID_NUM="20000"            # 與 login 節點一致
    export GID_NUM="20000"            # 與 login 節點一致
    export SHELL="/bin/bash"
    export HOME_DIR="/home/$USERNAME"

    # 1) 新增群組（同名方便對應 Slurm Account）
    sudo groupadd -g "$GID_NUM" "$GROUP"

    # 2) 新增使用者（固定 UID/GID；建立家目錄）
    sudo useradd -m -u "$UID_NUM" -g "$GROUP" -s "$SHELL" -d "$HOME_DIR" "$USERNAME"
    sudo passwd "$USERNAME"

    # 3) 驗證（在計算節點要能通過）
    getent passwd "$USERNAME"
    id "$USERNAME"
    ls -ld "$HOME_DIR"
    ```
- ### 長期建議（Best Practices）
    - **集中身份管理**：使用 **LDAP / FreeIPA / AD + SSSD**，讓所有節點的 `getent passwd` 統一來源，從根本避免 UID 漂移。
    - **共享家目錄**：以 NFS/並配合一致的 UID/GID。避免個別節點手動建家目錄造成落差。
    - **自動建家目錄**（選做）：可在 login/compute 啟用 `pam_mkhomedir`，首次登入自動建立；但**仍需**先解決 UID/GID 一致性。
    - **變更前維護窗口**：在調 UID/GID 前，安排維護時間，確保沒有作業在跑與檔案被占用。
- ### 追加檢查清單（Checklist）
    - [ ] `getent passwd admin` 在 **所有節點** 顯示相同 UID。
    - [ ] `getent group admin`（或目標群組）在所有節點顯示相同 GID。
    - [ ] `/home/admin` 擁有者為目標 UID\:GID，權限正確（`700` 起跳）。
    - [ ] NFS 伺服器導出的家目錄與各節點掛載點一致（含 `root_squash` 等選項符合政策）。
    - [ ] 重新測試：
        ```bash
        srun -p debug hostname            # 不應再出現 "going to /tmp"
        srun --chdir=/home/admin pwd      # 應回傳 /home/admin
        ```

<br>

---
---

<br>

## 討論
### 正確建立 user 的流程應為何？
- ### Question
    ```
    root@slurm-login-6fb5d948d6-5mcvp:~# sacctmgr create user user=tmp1 account=tj-account cluster=slurm
    There is no uid for user 'tmp1'
    Are you sure you want to continue? (You have 30 seconds to decide)
    (N/y): y
     Adding User(s)
      tmp1
     Settings
     Associations =
      C = slurm      A = tj-account           U = tmp1
    Would you like to commit changes? (You have 30 seconds to decide)
    (N/y): y
    ```
    正確建立 user 的流程應為何？

- ### gpt-5 (2025/08/28)
    你已經把 **Slurm 帳務(user/association)** 建起來了，但那個警告表示：系統裡沒有同名的 **作業系統帳號(UID)**。在 Slurm 裡，**作業最終是以該使用者的 UID/GID 在計算節點上執行**；若沒有 OS 帳號，提交或派發時通常會失敗（例如「user not found / no such uid」）。
    正確又穩當的流程如下（先作業系統，再 Slurm）：

    ---

    ### 建立使用者的標準流程

    #### 1) 先建立作業系統帳號（所有執行/登入環境都要看得到同一個 UID）

    * 裸機/VM（每台 login/compute 節點都要一致）：

    ```bash
    # 依你們的規劃選定固定 UID/GID，確保各節點一致
    sudo groupadd -r tj-account              # 選用；若已存在可略過
    sudo useradd -m -u 20011 -g tj-account -s /bin/bash tmp1
    sudo passwd tmp1

    # 驗證
    getent passwd tmp1
    id tmp1
    ```

    * 你目前是 Kubernetes + Slinky/Slurm：

      * **login pod** 和 **所有 slurmd compute pods** 內都要能解析到同一個 `tmp1`（同一 UID/GID）。
      * 常見做法：
        1. 用 LDAP/SSSD 提供集中式身份（建議）
        2. 或把 `/etc/passwd` & `/etc/group` 透過 ConfigMap / Secret / PVC 同步進 login + slurmd 映像/掛載。
      * 使用者家目錄 `/home/tmp1` 放在共享儲存（NFS／PVC），並在 login 與 compute pods 掛載同一路徑。

    > 重點：**不論哪種環境，提交端與執行端都必須看見同一個 UID**。

    ---

    #### 2) 建立/確認 Slurm 帳務物件（Account / User / Assoc / QOS）

    > 建議用以下順序檢查。

    ```bash
    # 建立(或確認) Account
    sacctmgr show account name=tj-account
    # 若沒有：
    # sacctmgr create account name=tj-account Organization=tj

    # 建立 User 並指定預設帳戶(DefAcct)
    sacctmgr create user name=tmp1 DefaultAccount=tj-account Cluster=slurm

    # (選用) 限定可用的 partition 或補充關聯
    sacctmgr add user name=tmp1 account=tj-account cluster=slurm partition=tn
    sacctmgr add user name=tmp1 account=tj-account cluster=slurm partition=debug
    
    # (選用) 指定/開放 QOS
    # 先確認有 normal（或你們定義的 QOS）
    sacctmgr show qos
    # 將可用 QOS 掛給使用者
    sacctmgr modify user name=tmp1 set qos=normal

    # (選用) 設定資源上限/配額
    sacctmgr modify user name=tmp1 set MaxJobs=10
    sacctmgr modify user name=tmp1 set MaxSubmitJobs=50
    sacctmgr modify user name=tmp1 set MaxTRESPerJob=cpu=32,mem=64G
    ```

    ---

    #### 3) 驗證關聯是否正確

    ```bash
    sacctmgr list user name=tmp1 withassoc format=User,DefAcct,Cluster,Account,Partition,QOS,MaxJobs,MaxTRES
    ```
    - 執行範例
        ```
        $ sacctmgr list user name=tmp1 withassoc format=User,DefaultAccount,Cluster,Account,Partition,QOS,MaxJobs,MaxTRES
              User   Def Acct    Cluster    Account  Partition                  QOS MaxJobs       MaxTRES 
        ---------- ---------- ---------- ---------- ---------- -------------------- ------- ------------- 
              tmp1 tj-account      slurm tj-account                          normal      10 cpu=32,mem=6+ 
              tmp1 tj-account      slurm tj-account      debug               normal      10 cpu=32,mem=6+ 
              tmp1 tj-account      slurm tj-account         tn               normal      10 cpu=32,mem=6+ 

        # ---

        $ sacctmgr list user name=tmp1 withassoc
              User   Def Acct     Admin    Cluster    Account  Partition     Share   Priority MaxJobs MaxNodes  MaxCPUs MaxSubmit     MaxWall  MaxCPUMins                  QOS   Def QOS 
        ---------- ---------- --------- ---------- ---------- ---------- --------- ---------- ------- -------- -------- --------- ----------- ----------- -------------------- --------- 
              tmp1 tj-account      None      slurm tj-account                    1                 10                32        50                                       normal           
              tmp1 tj-account      None      slurm tj-account      debug         1                 10                32        50                                       normal           
              tmp1 tj-account      None      slurm tj-account         tn         1                 10                32        50                                       normal
        ```

    ---

    #### 4) 以該使用者提交最小測試作業

    （在 login 節點/Pod，**切到 tmp1 身份** 測）

    ```bash
    # 切換身份（或用 ssh 登入 tmp1）
    sudo -iu tmp1
    # 沒有 sudo 或已經是 root 身份，則用 su 切換身份
    su - tmp1

    # 最小測試：指定帳戶與可用的分割區
    srun -A tj-account -p tn -N1 -n1 bash -lc 'whoami; id; hostname'
    # 或
    sbatch -A tj-account -p tn -N1 -n1 --wrap='hostname && whoami'
    ```

    若這步出錯、看到「user not found / uid 不存在」之類訊息，幾乎可確定是 **計算節點看不到該 OS 帳號/UID**（回到步驟 1 修正）。

    ---

    ### 常見問題與小抄

    * **我已在 sacctmgr 建了 user，但系統仍報 no uid？**
      sacctmgr 只管帳務/關聯；**真正執行需要 OS 帳號**。請先把 `tmp1` 的 OS 帳號與 UID/GID 在 login + 所有 compute 環境建好、且一致。

    * **Account vs Linux group 要一樣嗎？**
      不必，但很多團隊會「同名」方便管理（如 `tj-account` 同時當 Linux 群組與 Slurm Account）。

    * **K8s/Slinky 要點**

      1. 共享家目錄（PVC/NFS）
      2. 身分一致性（LDAP/SSSD 或同步 `/etc/passwd`）
      3. login 與 slurmd pods 的 **使用者資料一致**。

    ---

    照這個順序（OS 帳號 → Slurm 帳務 → 驗證 → 測試）做，之後新增使用者就會順暢且可預期。需要的話我可以幫你寫一份「在 K8s/Slinky 下同步使用者 & 家目錄」的具體操作手冊。


<br>

{%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}
