一、概述
Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从多个维度检测代码质量,通过插件形式,可以支持包括java、python、C#、go、scala、kotlin、JavaScrip、Groovy等二十几种编程语言的代码质量管理与检测。
下面使用docker 启动一个 sonarqube , 便于快速体验此平台提供的功能。
二、安装 SonarQube
你可以下载zip文件的传统方式安装SonarQube,也可以使用docker 镜像的方式启动 SonarQube容器。
1、 下载zip文件安装SonarQube https://www.sonarqube.org/downloads/
- 下载上图中的zip文件
- 解压缩zip文件,例如在C:\ sonarqube或/ opt / sonarqube中
- 运行下面的命令启动 SonarQube Server
# 在windows中,执行如下命令 C:\sonarqube\bin\windows-x86-64\StartSonar.bat # 在linux等其他系统中执行如下命令 /opt/sonarqube/bin/[OS]/sonar.sh console
2、使用docker 安装 SonarQube
- 在docker hub 中找到 sonarqube
- 使用
docker pull sonarqube
拉取镜像 - 运行下面的命令启动 SonarQube Server
docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest
3、登录SonarQube Server
实例启动并运行后,使用系统管理员凭据登录到 http://localhost:9000
- 用户名:admin
- 密码:admin
登录成功后需要重置密码
三、分析项目
登录成功后,如下图所示:
1、安装中文包
中文包安装成功后如下图
2、分析项目
- 单击创建新项目按钮。
- 给您的项目一个项目键和一个显示名称,然后单击设置按钮。
- 在“提供令牌”下,选择“生成令牌”。为您的令牌命名,点击生成按钮,然后点击继续。
- 在“对项目运行分析”下选择项目的主要语言,然后按照说明分析项目。在这里,您将在代码上下载并执行扫描程序(如果您使用的是Maven或Gradle,则会自动下载该扫描程序)。
- 使用Maven执行SonarQube分析是非常简单的。只需要在你的项目目录下执行如下命令。
mvn sonar:sonar \ -Dsonar.projectKey=test \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.login=a98ea942c2c4bd02b1621ee26653fe1b7007d83d
- 分析完成后,页面会自动刷新,您将在SonarQube上看到第一个分析:
四、遇到的问题
①执行上面的mvn命令,出现如下问题:
[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.8.0.2131:sonar (default-cli) on project quarkus-demo: Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property.
原因:项目只包含 .java 文件,没有编译成 .class 文件
解决:需要编译先项目,先执行 mvn pakage
再执行 mvn sonar: sonar
,也可以合并执行下面的命令
mvn package sonar:sonar \ -Dsonar.projectKey=test \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.login=a98ea942c2c4bd02b1621ee26653fe1b7007d83d
②执行上面的mvn命令,出现如下问题:
[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.7.0.1746:sonar (default-cli) on project mail-service: Not authorized. Please check the properties sonar.login and sonar.password. -> [Help 1]
报错原因是缺少用户密码,增加 -D”sonar.password=123456″ 参数,具体命令如下:
mvn clean verify sonar:sonar \ -Dsonar.projectKey=mail-service \ -Dsonar.projectName='mail-service' \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.login=admin \ -Dsonar.password=xxxx
③使用的镜像:sonarqube:lastest / sonarqube:9.8-community ,9.x 版本应该都会报错
启动命令(只是为了看能都启动成功) docker run sonarqube
报错如下:
2023.02.04 01:55:35 INFO app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /opt/sonarqube/temp 2023.02.04 01:55:35 INFO app[][o.s.a.es.EsSettings] Elasticsearch listening on [HTTP: 127.0.0.1:9001, TCP: 127.0.0.1:36696] 2023.02.04 01:55:35 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[ELASTICSEARCH] from [/opt/sonarqube/elasticsearch]: /opt/sonarqube/elasticsearch/bin/elasticsearch could not find java in ES_JAVA_HOME at /usr/lib/jvm/java-17-openjdk/bin/java 2023.02.04 01:55:35 WARN app[][o.s.a.p.AbstractManagedProcess] Process exited with exit value [ElasticSearch]: 1 2023.02.04 01:55:35 INFO app[][o.s.a.SchedulerImpl] Process[ElasticSearch] is stopped 2023.02.04 01:55:35 INFO app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and running 2023.02.04 01:55:35 INFO app[][o.s.a.SchedulerImpl] SonarQube is stopped
问题排查:
- 1:docker run -it sonarqube /bin/bash 进入镜像内部查看环境变量 JAVA_HOME 没问题
- 2:查看 jdk的权限设置,是不是es的启动用户看不到,发现也是正常的
- 3:想不出来其他的,9.x之前的镜像是没有问题的,于是百度
官方解决方案:could not find java in ES_JAVA_HOME at /opt/java/openjdk/bin/java · Issue #494 · SonarSource/docker-sonarqube · GitHub
原来是9.x 的镜像并没有处理linux的系统方案安全配置,需要我们手动配置
处理:
配置文件下载地址:https://github.com/moby/moby/blob/master/profiles/seccomp/default.json
命令:
docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 --security-opt=seccomp=/mnt/sonar/seccomp_profile.json sonarqube:latest
如果大家看不到,直接复制如下文件即可
{ "defaultAction": "SCMP_ACT_TRACE", "defaultErrnoRet": 1, "archMap": [ { "architecture": "SCMP_ARCH_X86_64", "subArchitectures": [ "SCMP_ARCH_X86", "SCMP_ARCH_X32" ] }, { "architecture": "SCMP_ARCH_AARCH64", "subArchitectures": [ "SCMP_ARCH_ARM" ] }, { "architecture": "SCMP_ARCH_MIPS64", "subArchitectures": [ "SCMP_ARCH_MIPS", "SCMP_ARCH_MIPS64N32" ] }, { "architecture": "SCMP_ARCH_MIPS64N32", "subArchitectures": [ "SCMP_ARCH_MIPS", "SCMP_ARCH_MIPS64" ] }, { "architecture": "SCMP_ARCH_MIPSEL64", "subArchitectures": [ "SCMP_ARCH_MIPSEL", "SCMP_ARCH_MIPSEL64N32" ] }, { "architecture": "SCMP_ARCH_MIPSEL64N32", "subArchitectures": [ "SCMP_ARCH_MIPSEL", "SCMP_ARCH_MIPSEL64" ] }, { "architecture": "SCMP_ARCH_S390X", "subArchitectures": [ "SCMP_ARCH_S390" ] }, { "architecture": "SCMP_ARCH_RISCV64", "subArchitectures": null } ], "syscalls": [ { "names": [ "accept", "accept4", "access", "adjtimex", "alarm", "bind", "brk", "capget", "capset", "chdir", "chmod", "chown", "chown32", "clock_adjtime", "clock_adjtime64", "clock_getres", "clock_getres_time64", "clock_gettime", "clock_gettime64", "clock_nanosleep", "clock_nanosleep_time64", "close", "close_range", "connect", "copy_file_range", "creat", "dup", "dup2", "dup3", "epoll_create", "epoll_create1", "epoll_ctl", "epoll_ctl_old", "epoll_pwait", "epoll_pwait2", "epoll_wait", "epoll_wait_old", "eventfd", "eventfd2", "execve", "execveat", "exit", "exit_group", "faccessat", "faccessat2", "fadvise64", "fadvise64_64", "fallocate", "fanotify_mark", "fchdir", "fchmod", "fchmodat", "fchown", "fchown32", "fchownat", "fcntl", "fcntl64", "fdatasync", "fgetxattr", "flistxattr", "flock", "fork", "fremovexattr", "fsetxattr", "fstat", "fstat64", "fstatat64", "fstatfs", "fstatfs64", "fsync", "ftruncate", "ftruncate64", "futex", "futex_time64", "futex_waitv", "futimesat", "getcpu", "getcwd", "getdents", "getdents64", "getegid", "getegid32", "geteuid", "geteuid32", "getgid", "getgid32", "getgroups", "getgroups32", "getitimer", "getpeername", "getpgid", "getpgrp", "getpid", "getppid", "getpriority", "getrandom", "getresgid", "getresgid32", "getresuid", "getresuid32", "getrlimit", "get_robust_list", "getrusage", "getsid", "getsockname", "getsockopt", "get_thread_area", "gettid", "gettimeofday", "getuid", "getuid32", "getxattr", "inotify_add_watch", "inotify_init", "inotify_init1", "inotify_rm_watch", "io_cancel", "ioctl", "io_destroy", "io_getevents", "io_pgetevents", "io_pgetevents_time64", "ioprio_get", "ioprio_set", "io_setup", "io_submit", "io_uring_enter", "io_uring_register", "io_uring_setup", "ipc", "kill", "landlock_add_rule", "landlock_create_ruleset", "landlock_restrict_self", "lchown", "lchown32", "lgetxattr", "link", "linkat", "listen", "listxattr", "llistxattr", "_llseek", "lremovexattr", "lseek", "lsetxattr", "lstat", "lstat64", "madvise", "membarrier", "memfd_create", "memfd_secret", "mincore", "mkdir", "mkdirat", "mknod", "mknodat", "mlock", "mlock2", "mlockall", "mmap", "mmap2", "mprotect", "mq_getsetattr", "mq_notify", "mq_open", "mq_timedreceive", "mq_timedreceive_time64", "mq_timedsend", "mq_timedsend_time64", "mq_unlink", "mremap", "msgctl", "msgget", "msgrcv", "msgsnd", "msync", "munlock", "munlockall", "munmap", "nanosleep", "newfstatat", "_newselect", "open", "openat", "openat2", "pause", "pidfd_open", "pidfd_send_signal", "pipe", "pipe2", "pkey_alloc", "pkey_free", "pkey_mprotect", "poll", "ppoll", "ppoll_time64", "prctl", "pread64", "preadv", "preadv2", "prlimit64", "process_mrelease", "pselect6", "pselect6_time64", "pwrite64", "pwritev", "pwritev2", "read", "readahead", "readlink", "readlinkat", "readv", "recv", "recvfrom", "recvmmsg", "recvmmsg_time64", "recvmsg", "remap_file_pages", "removexattr", "rename", "renameat", "renameat2", "restart_syscall", "rmdir", "rseq", "rt_sigaction", "rt_sigpending", "rt_sigprocmask", "rt_sigqueueinfo", "rt_sigreturn", "rt_sigsuspend", "rt_sigtimedwait", "rt_sigtimedwait_time64", "rt_tgsigqueueinfo", "sched_getaffinity", "sched_getattr", "sched_getparam", "sched_get_priority_max", "sched_get_priority_min", "sched_getscheduler", "sched_rr_get_interval", "sched_rr_get_interval_time64", "sched_setaffinity", "sched_setattr", "sched_setparam", "sched_setscheduler", "sched_yield", "seccomp", "select", "semctl", "semget", "semop", "semtimedop", "semtimedop_time64", "send", "sendfile", "sendfile64", "sendmmsg", "sendmsg", "sendto", "setfsgid", "setfsgid32", "setfsuid", "setfsuid32", "setgid", "setgid32", "setgroups", "setgroups32", "setitimer", "setpgid", "setpriority", "setregid", "setregid32", "setresgid", "setresgid32", "setresuid", "setresuid32", "setreuid", "setreuid32", "setrlimit", "set_robust_list", "setsid", "setsockopt", "set_thread_area", "set_tid_address", "setuid", "setuid32", "setxattr", "shmat", "shmctl", "shmdt", "shmget", "shutdown", "sigaltstack", "signalfd", "signalfd4", "sigprocmask", "sigreturn", "socketcall", "socketpair", "splice", "stat", "stat64", "statfs", "statfs64", "statx", "symlink", "symlinkat", "sync", "sync_file_range", "syncfs", "sysinfo", "tee", "tgkill", "time", "timer_create", "timer_delete", "timer_getoverrun", "timer_gettime", "timer_gettime64", "timer_settime", "timer_settime64", "timerfd_create", "timerfd_gettime", "timerfd_gettime64", "timerfd_settime", "timerfd_settime64", "times", "tkill", "truncate", "truncate64", "ugetrlimit", "umask", "uname", "unlink", "unlinkat", "utime", "utimensat", "utimensat_time64", "utimes", "vfork", "vmsplice", "wait4", "waitid", "waitpid", "write", "writev" ], "action": "SCMP_ACT_ALLOW" }, { "names": [ "process_vm_readv", "process_vm_writev", "ptrace" ], "action": "SCMP_ACT_ALLOW", "includes": { "minKernel": "4.8" } }, { "names": [ "socket" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 0, "value": 40, "op": "SCMP_CMP_NE" } ] }, { "names": [ "personality" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 0, "value": 0, "op": "SCMP_CMP_EQ" } ] }, { "names": [ "personality" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 0, "value": 8, "op": "SCMP_CMP_EQ" } ] }, { "names": [ "personality" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 0, "value": 131072, "op": "SCMP_CMP_EQ" } ] }, { "names": [ "personality" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 0, "value": 131080, "op": "SCMP_CMP_EQ" } ] }, { "names": [ "personality" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 0, "value": 4294967295, "op": "SCMP_CMP_EQ" } ] }, { "names": [ "sync_file_range2", "swapcontext" ], "action": "SCMP_ACT_ALLOW", "includes": { "arches": [ "ppc64le" ] } }, { "names": [ "arm_fadvise64_64", "arm_sync_file_range", "sync_file_range2", "breakpoint", "cacheflush", "set_tls" ], "action": "SCMP_ACT_ALLOW", "includes": { "arches": [ "arm", "arm64" ] } }, { "names": [ "arch_prctl" ], "action": "SCMP_ACT_ALLOW", "includes": { "arches": [ "amd64", "x32" ] } }, { "names": [ "modify_ldt" ], "action": "SCMP_ACT_ALLOW", "includes": { "arches": [ "amd64", "x32", "x86" ] } }, { "names": [ "s390_pci_mmio_read", "s390_pci_mmio_write", "s390_runtime_instr" ], "action": "SCMP_ACT_ALLOW", "includes": { "arches": [ "s390", "s390x" ] } }, { "names": [ "riscv_flush_icache" ], "action": "SCMP_ACT_ALLOW", "includes": { "arches": [ "riscv64" ] } }, { "names": [ "open_by_handle_at" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_DAC_READ_SEARCH" ] } }, { "names": [ "bpf", "clone", "clone3", "fanotify_init", "fsconfig", "fsmount", "fsopen", "fspick", "lookup_dcookie", "mount", "mount_setattr", "move_mount", "name_to_handle_at", "open_tree", "perf_event_open", "quotactl", "quotactl_fd", "setdomainname", "sethostname", "setns", "syslog", "umount", "umount2", "unshare" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_ADMIN" ] } }, { "names": [ "clone" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 0, "value": 2114060288, "op": "SCMP_CMP_MASKED_EQ" } ], "excludes": { "caps": [ "CAP_SYS_ADMIN" ], "arches": [ "s390", "s390x" ] } }, { "names": [ "clone" ], "action": "SCMP_ACT_ALLOW", "args": [ { "index": 1, "value": 2114060288, "op": "SCMP_CMP_MASKED_EQ" } ], "comment": "s390 parameter ordering for clone is different", "includes": { "arches": [ "s390", "s390x" ] }, "excludes": { "caps": [ "CAP_SYS_ADMIN" ] } }, { "names": [ "clone3" ], "action": "SCMP_ACT_ERRNO", "errnoRet": 38, "excludes": { "caps": [ "CAP_SYS_ADMIN" ] } }, { "names": [ "reboot" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_BOOT" ] } }, { "names": [ "chroot" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_CHROOT" ] } }, { "names": [ "delete_module", "init_module", "finit_module" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_MODULE" ] } }, { "names": [ "acct" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_PACCT" ] } }, { "names": [ "kcmp", "pidfd_getfd", "process_madvise", "process_vm_readv", "process_vm_writev", "ptrace" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_PTRACE" ] } }, { "names": [ "iopl", "ioperm" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_RAWIO" ] } }, { "names": [ "settimeofday", "stime", "clock_settime", "clock_settime64" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_TIME" ] } }, { "names": [ "vhangup" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_TTY_CONFIG" ] } }, { "names": [ "get_mempolicy", "mbind", "set_mempolicy" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYS_NICE" ] } }, { "names": [ "syslog" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_SYSLOG" ] } }, { "names": [ "bpf" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_BPF" ] } }, { "names": [ "perf_event_open" ], "action": "SCMP_ACT_ALLOW", "includes": { "caps": [ "CAP_PERFMON" ] } } ] }