# [CMS Online Judge] 安裝教學
:::info
目錄:
* [[CMS Online Judge] Docker安裝教學](/WKsC33XYRme4sM-Kkst_XA)
* [[CMS Online Judge] 完整安裝教學](/qLOLKTjlQ6ivpN0vg4yb-g)
* [[CMS Online Judge] 使用教學](/vzeJxoVGQPipzqd3R0_s9w)
* [[CMS Online Judge] 互動題、Checker](/cA70QEPVRROxvTxYujMTcw)
* [[CMS Online Judge] 給系統管理者的一些建議](/EOf5VvLOSM6BTjbVfb7vRg)
[Github連結](https://github.com/erichung09060/cms)
前言:
由於[cms](https://cms-dev.github.io/)在網路上根本沒有中文教學,就連英文都只有論壇而已,官方文件又臭又長,對有需求的人和初學者很不友善,因此這篇文章就誕生了。
在這篇文章裡,我修復了一些pip套件相容性的問題,你可以放心地使用python3.10(當然有3.8最好),且cms也是使用最新版本。如果你想快速安裝可以使用Docker,請參考[這篇](/WKsC33XYRme4sM-Kkst_XA)。
:::
## 安裝教學
:::success
**主機環境:**
Ubuntu : 20.04或22.04
Python and pip : 3.8或3.10
Cgroup Version: 1 (cms只允許v1)
查看Cgroup版本
```
sudo apt install docker.io -y
sudo docker info | grep 'Cgroup Version'
```
如果是v2要切換到v1。
```
sudo sed -i '/GRUB_CMDLINE_LINUX=/c\GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"' /etc/default/grub
sudo update-grub
sudo reboot
```
:::
**首先更新所有套件**
```
sudo apt update && sudo apt upgrade -y
```
**下載cms會用到的套件(包括官方和我實測後發現還需要安裝的)**
```
sudo apt install build-essential openjdk-11-jdk-headless fp-compiler postgresql postgresql-client cppreference-doc-en-html cgroup-lite libcap-dev zip git vim python3-dev libcups2-dev libpq-dev python3-cffi python3-pip -y
```
**把cms從github上載下來**
```
git clone https://github.com/erichung9060/CMS_Online_Judge.git && cd CMS_Online_Judge
```
**加入cms user**
```
sudo python3 prerequisites.py --yes --cmsuser=cmsuser install
```
做完後記得要Logout再Login,記得回到cms資料夾
```
logout
cd CMS_Online_Judge
```
**安裝python套件**
```
sudo --preserve-env="stdlib" pip install -r requirements.txt
```
**初始化**
```
sudo --preserve-env="stdlib" python3 setup.py install
```
:::spoiler 查看python版本
```
python3 --version
```
:::
:::spoiler **修Bug(Python 3.10才需要修,3.8可直接跳過)**
進到vim後直接打要修改的行號加`gg`,就會跳到該行,接著按$i$進入編輯模式,修改完後按esc並輸入`:wq`退出vim。
🐞1️⃣
```
sudo vim /usr/local/lib/python3.10/dist-packages/jinja2/tests.py
```
在13行改成以下形式
```
from collections.abc import Mapping
```
🐞2️⃣
```
sudo vim /usr/local/lib/python3.10/dist-packages/tornado/httputil.py
```
在106行改成以下形式
```
class HTTPHeaders(collections.abc.MutableMapping):
```
:::
</br>
**進入資料庫**
```
sudo su - postgres
```
**設定資料庫和密碼,記住這組密碼等下會需要**
```
createuser --username=postgres --pwprompt cmsuser
createdb --username=postgres --owner=cmsuser cmsdb
psql --username=postgres --dbname=cmsdb --command='ALTER SCHEMA public OWNER TO cmsuser'
psql --username=postgres --dbname=cmsdb --command='GRANT SELECT ON pg_largeobject TO cmsuser'
```
**退出資料庫**
```
logout
```
**進入cms.conf**
把第59行的`0000`替換成剛設定的密碼
```
sudo vim /usr/local/etc/cms.conf
```
**初始化資料庫**
```
sudo cmsInitDB
```
**更換Secret Key**
官方文件建議每一場比賽都要換一個新的secret key
```
sudo sed -i "s/8e045a51e4b102ea803c06f92841a1fb/`python3 -c "from cmscommon import crypto; print(crypto.get_hex_random_key())"`/g" /usr/local/etc/cms.conf;
```
**建立一個admin帳號(他會回傳密碼給你)**
格式為:cmsAddAdmin <admin name>
```
sudo cmsAddAdmin admin
```
**啟動admin管理介面**
```
sudo cmsAdminWebServer
```
接著開啟管理介面,網址:`localhost:8889`或`ip:8889`
:::spoiler 另一種連進server的方法
安裝ngrok
```
sudo snap install ngrok
```
設定token,這裡提供一組token給有需要的人,也可以自己去ngrok辦帳號,即可拿到一組免費的token。
```
ngrok config add-authtoken 2KUJojRTP1PpeXrH8dXbvkIjnQ7_NGaERvrUNJPnQJtjK2H5
```
最後設定要訪問的網址
```
ngrok http localhost:8889
```
複製這串網址就可以用啦~

:::
<br/>
**接著在admin管理介面新增使用者帳密、題目以及一場比賽,至於怎麼建立比賽可參考[CMS Online Judge 使用教學](/vzeJxoVGQPipzqd3R0_s9w)**
建立好比賽後按ctrl+C終止cmsAdminWebServer。
:::spoiler 也可直接匯入範例比賽,執行以下指令即可。
```
sudo cmsImportUser --all -L italy_yaml Sample_Contest;
sudo cmsImportContest -i -L italy_yaml Sample_Contest;
```
:::
<br/>
**開啟Ranking介面**
計分板網址:`localhost:8890`
```
sudo cmsRankingWebServer
```
**開啟比賽介面**
```
sudo cmsResourceService -a
```
如果只有一場比賽就輸入$1$,否則看要開啟哪一場比賽
比賽網址:`localhost:8888`
**最後就大功告成啦🎉試著登入並Submit看看吧**
---------------
## 補充
1. cms安裝位置
```
/usr/local/lib/python3.8/dist-packages/cms-1.5.dev0-py3.8.egg
```
2. 可查看cms的Log來Debug
```
sudo cmsLogService
```
2. 如要使用計分板的話要記得先執行`cmsRankingWebServer`,`cmsResourceService -a`會啟用所有的物件但不包括`cmsRankingWebServer`。
3. DB預設密碼為`0000`,如果cms只是測試用可把密碼設定成`0000`就不用再改cms.conf了。
4. 刪除整個CMS :
```
sudo rm -rf \
/var/local/lib/cms \
/var/local/run/cms \
/var/local/cache/cms \
/var/local/log/cms \
/usr/local/lib/python3.8/dist-packages/cms-1.5.dev0-py3.8.egg \
/usr/local/etc/cms.conf \
/usr/local/etc/cms.ranking.conf \
/usr/local/bin/cmsRunTests \
/usr/local/bin/cmsResourceService \
/usr/local/bin/cmsAddTestcases \
/usr/local/bin/cmsPrintingService \
/usr/local/bin/cmsSpoolExporter \
/usr/local/bin/cmsDropDB \
/usr/local/bin/cmsAddAdmin \
/usr/local/bin/cmsEvaluationService \
/usr/local/bin/cmsAddSubmission \
/usr/local/bin/cmsRemoveContest \
/usr/local/bin/cmsAddParticipation \
/usr/local/bin/cmsInitDB \
/usr/local/bin/cmsProxyService \
/usr/local/bin/cmsDumpImporter \
/usr/local/bin/cmsChecker \
/usr/local/bin/cmsWorker \
/usr/local/bin/cmsRemoveUser \
/usr/local/bin/cmsAddTeam \
/usr/local/bin/cmsDumpExporter \
/usr/local/bin/cmsRemoveSubmissions \
/usr/local/bin/cmsImportUser \
/usr/local/bin/cmsImportTask \
/usr/local/bin/cmsImportContest \
/usr/local/bin/cmsAdminWebServer \
/usr/local/bin/cmsDumpUpdater \
/usr/local/bin/cmsImportTeam \
/usr/local/bin/cmsRWSHelper \
/usr/local/bin/cmsRankingWebServer \
/usr/local/bin/cmsLogService \
/usr/local/bin/cmsImportDataset \
/usr/local/bin/cmsMake \
/usr/local/bin/cmsCleanFiles \
/usr/local/bin/cmsRemoveParticipation \
/usr/local/bin/cmsExportSubmissions \
/usr/local/bin/cmsContestWebServer \
/usr/local/bin/cmsAddUser \
/usr/local/bin/cmsRemoveTask \
/usr/local/bin/cmsAddStatement \
/usr/local/bin/cmsScoringService \
/usr/local/share/cms \
/usr/local/include/cms \
/var/local/lib/isolate \
/usr/local/bin/isolate \
/usr/local/etc/isolate \
```
```
for i in {0..9}; do sudo rm -rf $(sudo find /tmp -name "cms*$i"); done
```
```
for i in {a..z}; do sudo rm -rf $(sudo find /tmp -name "cms*$i"); done
```
```
sudo rm -rf $(sudo find /tmp -name "cms*_")
```
```
sudo userdel cmsuser
sudo userdel postgres
```
5. 如有無法執行的指令請查看[CMS官方文件](https://cms.readthedocs.io/en/latest/index.html),以官方文件為準