การติดตั้ง Sonar Scanner และการ config
การติดตั้งและใช้งาน sonar scanner นั้นมีความสำคัญมากเนื่องจาก sonar scanner เป็นเครื่องมือที่ทำหน้าที่ scan source code แล้วส่งผลกลับไปยัง SonarQube server ในบทความนี้เราจะนำทุกท่านไปดูวิธีการติดตั้งและใช้งานในแต่ละ platform กันเลย
- การติดตั้ง sonar scanner บน windows
- การติดตั้ง sonar scanner บน MacOS
- การใช้งาน sonar scanner ผ่านทาง docker
- การกำหนดค่า configuration ของ sonar scanner
ก่อนเริ่มต้นติดตั้ง sonar-scanner นั้นต้องมีสิ่งนี้ก่อน
- Project Key unique key ที่จะใช้อ้างถึง project ที่เราสร้างไว้บน SonarQube Server
- Token Authentication token ที่ต้องมีสิทธิในการเข้าถึง project ที่เราอ้างถึงด้วย projectKey
Token ที่เรา Generate ขึ้นมาตอนสร้าง project จะเป็น Project analysis tokens คือใช้ได้แค่ใน project ที่เรากำลังสร้างขึ้นมาเท่านั้น
ดูขั้นตอน การสร้าง SonarQube project และการ Generate Token ได้ที่นี่
การติดตั้ง Sonar Scanner บน Windows
-
ติดตั้ง sonar-scanner โดย download sonar-scanner-cli ได้ตาม link นี้
-
เลือก windows-64 bits
-
แตก Zip ไฟล์แล้ว Copy ไปยัง path ที่สามารถอ้างถึงได้ง่าย เช่น C:\sonar-scanner-4.8.0.2856-windows
-
เปิดหน้า Edit Environment Variables เลือกตัวแปร PATH แล้วก็ Add บรรทัดนี้เข้าไป
C:\sonar-scanner-4.8.0.2856-windows\bin
** ควรเก็บเลข version ไว้จะได้รู้ว่าตอนนี้ sonar-scanner ของเราเป็น version อะไร **
-
สั่ง run command นี้ใน directory ที่มี source code ได้เลย
sonar-scanner.bat -Dsonar.host.url=http://localhost:9000 \ -Dsonar.token=[Token ที่ได้จาก Sonarqube Server] -Dsonar.projectKey=demo:project -Dsonar.projectName=GoTest # ถ้าไม่ได้กำหนดก็จะใช้ project Key แทน -Dsonar.sources=.
-
กลับไปดูผลลัพธ์บน SonarQube Server จะได้ผลดังรูป
การติดตั้ง sonar scanner บน MacOS
การติดตั้ง sonar scanner บน MacOS นั้นเราสามารถ install ผ่าน brew ได้เลย โดยเราแค่ run command
brew install sonar-scanner
ถ้าในกรณีที่เราเปิด terminal ขึ้นมาแล้วไม่สามารถ run sonar-scanner ได้ให้ทำการแก้ไขดังนี้
-
ตรวจสอบว่า shell ที่เราใช้นั้นเป็น bash หรือ zsh ด้วยคำสั่ง
echo $0
หรือ
echo $SHELL
-
เปิดไฟล์ .zshrc หรือ .bashrc ขึ้นมา ซึ่งขึ้นอยู่กับ shell ที่คุณใช้ว่าเป็นตัวไหน ถ้าเครื่องคุณเป็น bash ให้เปิดไฟล์ .bashrc แต่ถ้าเป็น zsh ให้เปิดไฟล์ .zshrc ขึ้นมา แต่ถ้ายังไม่มีไฟล์นี้อยู่ในเครื่องก็สร้างขึ้นมาใหม่ได้เลย หลังจากนั้นให้ใส่คำสั่งนี้ลงไป
export SONAR_HOME=/usr/local/Cellar/sonar-scanner/{version}/libexec export SONAR=$SONAR_HOME/bin export PATH=$SONAR:$PATH
แทนที่ {version} ด้วย version ของ sonar-scanner ที่ install
-
หลังจากนั้นให้ run คำสั่งนี้ได้เลย
sonar-scanner -Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=[Token ที่ได้จาก Sonarqube Server]
-Dsonar.projectKey=demo:project
-Dsonar.projectName=GoTest # ถ้าไม่ได้กำหนดก็จะใช้ project Key แทน
-Dsonar.sources=.
การใช้งาน sonar-scanner ผ่านทาง docker
ส่วนสุดท้ายจะเป็นการ run sonar scanner ด้วย docker ซึ่งตัว sonar scanner นั้นจะเป็นผู้ scan และส่งผลลัพธ์กลับขึ้นไปยัง sonarqube server ดังนั้นเราสามารถเลือกได้ว่าจะติดตั้งผ่านทาง command line หรือจะ run ผ่าน docker ซึ่งการ run ผ่าน docker จะใช้คำสั่งนี้
docker run --rm -it -v ${PWD}:/usr/src \
--network host \
--name sonar-scanner \
-e SONAR_HOST_URL="http://localhost:9000" \
-e SONAR_LOGIN="TOKEN" \
sonarsource/sonar-scanner-cli
สิ่งที่ต้องเข้าใจในการใช้งาน sonar-scanner ผ่านทาง docker คือ
-
คุณต้องนำ source code เข้าไปไว้ใน container โดยใช้ -v ทำการ bind mount folder ปัจจุบันนี้เข้าไปยัง /usr/src (sonar scanner จะทำการ scan folder /usr/src) ดังนั้นถ้าคุณ run command นี้จาก folder อื่นที่ไม่ใช่ source code ให้เปลี่ยน ${PWD} เป็น path เต็มที่ระบุไปยัง source code ที่เราต้องการ scan
1 2 3
docker run --rm -it -v ${PWD}:/usr/src \ ... sonarsource/sonar-scanner-cli
-
คุณต้องส่งผลลัพธ์ขึ้นไปที่ sonarqube server ดังนั้น sonar scanner ต้องอยู่ใน network เดียวกับ sonarqube server โดยเรามีทางเลือกหลายทาง ดังนี้
-
set network ให้เป็น network เดียวกับเครื่อง host เราจะสามารถอ้างถึง sonarqube server ผ่านทาง localhost ได้เลย
1 2 3 4 5
docker run --rm -it -v ${PWD}:/usr/src \ --network host \ -e SONAR_HOST_URL="http://localhost:9000" \ ... sonarsource/sonar-scanner-cli
-
link sonar scanner cli กับ container ของ sonarqube server คำว่า sonarqube ใน บรรทัดที่ 2 หมายถึงชื่อ container เราต้องตั้งชื่อตอนเรา run container ของ sonarqube server ขึ้นมา ด้วย - -name sonarqube ส่วนตอนอ้างถึง url ของ sonarqube server ให้ใช้ชืื่อ container แทน แบบในบรรทัดที่ 3
1 2 3 4 5
docker run --rm -it -v ${PWD}:/usr/src \ --link sonarqube \ -e SONAR_HOST_URL="http://sonarqube:9000" \ ... sonarsource/sonar-scanner-cli
-
set network เป็น network เดียวกับ docker compose ในกรณีนี้เราจะนำ sonar scanner cli ไปใส่ไว้ใน network ของ docker compose ถ้าเราไม่ได้ตั้งชื่อ network ใน docker-compose.yml ชื่อของ network จะเป็นชื่อ folder ที่เรา run docker-compose up ให้เราตรวจสอบรายชื่อ network ด้วยคำสั่ง
docker network ls
หลังจากนั้นก็ใส่ชื่อ network นี้เข้าไปในบรรทัดที่ 2
1 2 3 4 5
docker run --rm -it -v ${PWD}:/usr/src \ --network [ชื่อของ docker-compose network] \ -e SONAR_HOST_URL="http://sonarqube:9000" \ ... sonarsource/sonar-scanner-cli
ส่วน URL จะใช้ชื่อของ service ที่เราประกาศไว้ใน docker compose ซึ่งจากตัวอย่าง docker-compose.yml ด้านบน ชื่อของ service ที่ใช้เป็น URL จะอยู่ในบรรทัดที่ 3
-
ส่วนต่อไปก็คือ token ที่ใช้ในการ login ซึ่งเราได้มาตอน create project หรือถ้าเราต้องการไป generate token ใหม่ให้ทำตามนี้
- ให้เข้าไปที่ My Account > Security
- ให้ตั้งชื่อ token
- เลือก type เป็น Project analysis tokens
- กำหนด expire ตามต้องการ(ยิ่งกำหนดให้นานเท่าไหร่ยิ่งไม่ปลอดภัย)
- กดปุ่ม Generate แล้วก็ copy token ออกมาใช้งานต่อได้เลย
เมื่อได้ token ที่ต้องการแล้วให้นำ token มาใส่ไว้ในบรรทัดที่ 5 หลังจากนี้เราก็สามารถ run sonar-scanner-cli ผ่านทาง docker ได้แล้ว
1 2 3 4 5 6
docker run --rm -it -v ${PWD}:/usr/src \ --network host \ --name sonar-scanner \ -e SONAR_HOST_URL="http://localhost:9000" \ -e SONAR_LOGIN="d32ede54513ec7b92589139aaaa5781c121a9303" \ sonarsource/sonar-scanner-cli
-
ถ้าต้องการใส่ options อื่นๆเพิ่มเติมสามารถต่อท้ายแบบนี้ได้เลย
1 2 3 4 5 6
docker run --rm -it -v ${PWD}:/usr/src \ --network host \ --name sonar-scanner \ -e SONAR_HOST_URL="http://localhost:9000" \ -e SONAR_LOGIN="d32ede54513ec7b92589139aaaa5781c121a9303" \ sonarsource/sonar-scanner-cli -Dsonar.qualitygate.wait=true
-
Sonar-project.properties มีไว้ทำไม?
การกำหนดค่าให้กับ sonar-scanner ในตัวอย่างก่อนหน้านั้นใช้วิธีการส่งเข้าไปใน parameters ของ sonar-scanner โดยตรงซึ่งถ้าจำนวนของ parameters นั้นมีเยอะมากๆ เช่น
sonar-scanner.bat -Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=[Token ที่ได้จาก Sonarqube Server]
-Dsonar.projectKey=demo:project
-Dsonar.projectName=InsecureApp
-Dsonar.projectVersion=1.2
-Dsonar.sources=./src/main/java
-Dsonar.tests=./src/test/java
-Dsonar.exclusions=./src/foo
-Dsonar.dependencies=./mvn
-Dsonar.qualitygate.wait=true
ซึ่งในบางกรณีเราอาจต้องการกำหนดค่าของ configuration มากกว่านี้อีกหลายตัว SonarQube เลยมีทางเลือกมาให้เราจัดการกับ configuration ได้ง่ายขึ้น โดยที่เราสามารถสร้าง file ที่ชื่อว่า sonar-project.properties แล้ววางไว้ใน directory ที่เราต้องการ run sonar-scanner ซึ่งใน file นี้จะระบุ configuration ทุกอย่างที่เราต้องการลงไปได้เลย และเมื่อ configuration ในการ scan อยู่ที่เดียวกับ source code(อาจวางไว้คนละที่ได้ถ้าต้องการ) เวลาส่งให้คนอื่น scan เราก็ไม่ต้องระบุ parameter อะไรเลย เราแค่สั่ง sonar-scanner แค่อย่างเดียว
เราจะใช้งาน sonar-project.properties ได้ด้วยขั้นตอนต่างๆ ดังนี้
-
สร้างไฟล์ sonar-project.properties ใน root directory ของ repository
# ห้ามซ้ำกันในแต่ละ server sonar.projectKey=demo:insecureapp # project metadata (ถ้าไม่ใส่จะใช้ project key แทน) sonar.projectName=Insecure Application Demo # ระบุ project Version sonar.projectVersion=1.2 # path ที่มี source code sonar.sources=./src/main/java # บอก sonar-scanner ว่า path ไหนเป็น test # เราจะไม่ scan source code ที่ใช้เขียน test case sonar.tests=./src/test/java # path ที่ไม่ต้องการให้ scan เช่น html sonar.exclusions=./src/view # ที่อยู่ของ SonarQube Server sonar.host.url=http://localhost:9000 # ถ้าเป็น Java ต้องระบุ path ของ Java ที่ติดตั้งไว้ในเครื่อง sonar.java.binaries=/Library/Java/JavaVirtualMachines/openjdk.jdk/Contents/Home # รอจนกว่า server จะตอบกลับมาว่า ผ่าน quality gate หรือไม่ sonar.qualitygate.wait=true
-
หลังจากนั้นให้ cd เข้าไปใน folder ที่มีไฟล์ sonar-project.properties แล้ว run คำสั่งนี้
sonar-scanner -Dsonar.token=[Token ที่ได้จาก Sonarqube Server]
ไม่ควรจะนำ Token ไปใส่ใน sonar-project.properties เพราะ token ถือว่าเป็นความลับที่ต้องจัดเก็บไว้อย่างนี้ ควรจะเก็บแยกไว้ต่างหาก
เพียงแค่นี้เราก็ไม่ต้องปวดหัวกับการส่ง parameters ยาวๆใน sonar-scanner อีกต่อไป แต่ถ้าคุณต้องการ override ค่าต่างๆเราจะสามารถเปลี่ยนแปลงค่าต่างๆ ผ่านทาง parameters ตอน run ได้เลยเช่น
sonar-scanner -Dsonar.token=[Token ที่ได้จาก Sonarqube Server] -Dsonar.host.url=https://sonarqube-other-server
sonar-scanner จะนำ https://sonarqube-other-server ไปแทนที่ http://localhost:9000 ที่กำหนดไว้ใน sonar-project.properties ทันที ดังนั้นสิ่งที่คุณต้องเข้าใจคือ ลำดับในการอ่านค่า configuration ของ sonar-scanner จะเรียงตามนี้
ดังนั้นเวลากำหนดให้ Analyzer ทำงานนั้นเราจะเริ่มจาก
- กำหนดค่าใน Global Properties (ผ่านหน้า GUI ใน sonarqube server) โดยเข้าไปที่ี Administration > Configuration > General Settings
- กำหนดค่าใน Project Properties (ผ่านหน้า GUI ใน sonarqube server) โดยเข้าไปที่ Project Settings > General Settings
- กำหนดค่าใน sonar-project.properties
- กำหนดค่าโดยส่งผ่าน paramerters -D ใน command line