Tools-Jenkins-pipeline
jenkins使用pipeline
脚本名词解释
pipeline
<必须> Pipeline是CD管道的用户定义模型。Pipeline的代码定义了您的整个构建过程,通常包括构建应用程序,测试和交付应用程序的阶段。
agent
<必须> 定义pipeline的执行环境,必须存在
stages
<阶段> 包含多个子阶段stage(‘子阶段名’)
jenkins 的工作空间目录 /var/jenkins_home/workspace/
node vs agent 区别
agent是声明性的pipelines,node是脚本性的pipelines
实践
pipeline使用gradle
学习到如何使用工具,和配置工具全局变量
配置工具
系统管理->全局工具配置->Gradle->Gradle 安装
name:gradle4.8
- 自动安装
版本 Gradle 4.8
Apply->Save
即可注释:如果没有Gradle设置,先去安装Gradle插件,默认推荐设置是安装了的
编写Jenkinsfile进行测试
1
2
3
4
5
6
7
8#!/usr/bin/env groovy Jenkinsfile
node {
def gradleHome = tool 'gradle4.8' //这里的gradle4.8要和gradle工具的配置里的name要一致
env.PATH = "${gradleHome}/bin:${env.PATH}"
stage('build') {
sh 'gradle -v'
}
}
pipeline使用gradle打包java spring boot
1 | #!/usr/bin/env groovy Jenkinsfile |
打包jar为镜像
1 | #!/usr/bin/env groovy Jenkinsfile |
运行镜像
1 | #!/usr/bin/env groovy Jenkinsfile |
pipeline 环境变量选择设置
**严重注意**
这个需要第二次运行才会生效,第一次设置之后运行,不会出来,第二次拉去运行才会出来
1 | #!/usr/bin/env groovy Jenkinsfile |
pipeline agent版gradle脚本
not support tool "gradle4.8"
单个设置
1 | #!/usr/bin/env groovy Jenkinsfile |
申明式使用脚本式语言script
1 | #!/usr/bin/env groovy Jenkinsfile |
环境变量
env.BUILD_ID 当前的编译id,和Jenkins versions 1.597+ 的env.BUILD_NUMBER一样
env.JOB_NAME 当前项目名
env.JENKINS_URL only available if Jenkins URL set in “System Configuration”
git diff HEAD^ eurekaserver/
和上个版本比较eurekaserver目录,可以不要
常见问题
提示如下错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45> git --version # timeout=10
> git --version # 'git version 1.8.3.1'
using GIT_ASKPASS to set credentials
> git ls-remote http://gitlab.admin.exxk.com.cn/exxk/exxk-server.git # timeout=10
> git rev-parse --resolve-git-dir /var/jenkins_home/caches/git-d065127b6d5e88dbce5baaa6da0dd31a/.git # timeout=10
Setting origin to http://gitlab.admin.exxk.com.cn/exxk/exxk-server.git
> git config remote.origin.url http://gitlab.admin.exxk.com.cn/exxk/exxk-server.git # timeout=10
Fetching & pruning origin...
Listing remote references...
> git config --get remote.origin.url # timeout=10
> git --version # timeout=10
> git --version # 'git version 1.8.3.1'
using GIT_ASKPASS to set credentials
> git ls-remote -h http://gitlab.admin.exxk.com.cn/exxk/exxk-server.git # timeout=10
Fetching upstream changes from origin
> git config --get remote.origin.url # timeout=10
using GIT_ASKPASS to set credentials
> git fetch --tags --progress --prune origin +refs/heads/*:refs/remotes/origin/* # timeout=10
ERROR: [星期三 六月 29 07:55:33 UTC 2022] Could not fetch branches from source
[星期三 六月 29 07:55:33 UTC 2022] Finished branch indexing. Indexing took 0.5 秒
FATAL: Failed to recompute children of prd-exxk6xljd » prd-exxk-server
hudson.plugins.git.GitException: Command "git fetch --tags --progress --prune origin +refs/heads/*:refs/remotes/origin/*" returned status code 1:
stdout:
stderr: error: there are still refs under 'refs/remotes/origin/release'
From http://gitlab.admin.exxk.com.cn/exxk/exxk-server
! [new branch] release -> origin/release (unable to update local ref)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2671)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandWithCredentials(CliGitAPIImpl.java:2096)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.access$500(CliGitAPIImpl.java:84)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl$1.execute(CliGitAPIImpl.java:618)
at jenkins.plugins.git.AbstractGitSCMSource$8.run(AbstractGitSCMSource.java:602)
at jenkins.plugins.git.AbstractGitSCMSource$8.run(AbstractGitSCMSource.java:588)
at jenkins.plugins.git.AbstractGitSCMSource.doRetrieve(AbstractGitSCMSource.java:394)
at jenkins.plugins.git.AbstractGitSCMSource.doRetrieve(AbstractGitSCMSource.java:350)
at jenkins.plugins.git.AbstractGitSCMSource.retrieve(AbstractGitSCMSource.java:588)
at jenkins.scm.api.SCMSource._retrieve(SCMSource.java:373)
at jenkins.scm.api.SCMSource.fetch(SCMSource.java:283)
at jenkins.branch.MultiBranchProject.computeChildren(MultiBranchProject.java:641)
at com.cloudbees.hudson.plugins.folder.computed.ComputedFolder.updateChildren(ComputedFolder.java:278)
at com.cloudbees.hudson.plugins.folder.computed.FolderComputation.run(FolderComputation.java:166)
at jenkins.branch.MultiBranchProject$BranchIndexing.run(MultiBranchProject.java:1032)
at hudson.model.ResourceController.execute(ResourceController.java:101)
at hudson.model.Executor.run(Executor.java:442)
Finished: FAILURE分析:关键错误
error: there are still refs under 'refs/remotes/origin/release' From http://gitlab.admin.exxk.com.cn/exxk/exxk-server ! [new branch] release -> origin/release (unable to update local ref)
这句表示本地已经有release分支了,服务器的release删了,然后又重新建了,导致不一样,解决清空本地分支,执行git remote prune origin
删除旧的分支和冲突分支,但是这是在jenkins里面删除难度较大,因此采用删除git在jenkins里面的缓存,因此需要找到分支的缓存,可以在日志git rev-parse --resolve-git-dir /var/jenkins_home/caches/git-d065127b6d5e88dbce5baaa6da0dd31a/.git
这一行发现缓存的目录解决:登录jenkins容器,进入
cd /var/jenkins_home/caches/
然后删除或重命名git-d065127b6d5e88dbce5baaa6da0dd31a
和git-d065127b6d5e88dbce5baaa6da0dd31a@tmp
即可总结:kubesphere的devops流程是,先在jenkins容器里面扫描git里面的jenkins部署脚本,然后缓存,然后启动新的容器根据jekins部署脚本拉取代码,运行编译过程。
流水线卡在
‘Jenkins’ doesn’t have label ‘maven’
这个提示分析:检查jekins输出了一个info信息
Maximum number of concurrently running agent pods (100) reached for Kubernetes Cloud kubernetes, not provisioning: 100 running or pending in namespace kubesphere-devops-system with Kubernetes labels {jenkins=slave}
这句话意思是agent pods 已经有100个在运行或pending等待中,然后执行kubectl get pod -A
发行maven和nodejs的代理镜像加起来刚刚100个,都处于error状态。解决:执行
kubectl delete pod maven-xxx -n kubesphere-devops-system
进行删除错误的pod。总结:注意每个日志,不是错误警告日志,也要注意重复多次的提示信息。
在2基础上分析为什么有100个error的pod,执行
kubectl logs maven-0n5wf -n kubesphere-devops-system
提示如下错误1
error: a container name must be specified for pod maven-0n5wf, choose one of: [jnlp maven]
在执行
kubectl logs maven-0n5wf -n kubesphere-devops-system -c jnlp
提示如下错误1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22```
4. [ks-jenkins:2.249.1](registry.cn-beijing.aliyuncs.com/kubesphereio/ks-jenkins:2.249.1)启动出现异常,找不到原因时,快速删除缓存重建配置可以解决大多数问题。执行
````bash
#命令详解:ls列举所有文件然后通过管道grep ,-v代表反转,-E代表正则,多个匹配,去掉-v可以检查正则是否正确
#该命令是删除除了jobs、secret.key、secret.key.not-so-secret、secrets、userContent、users、workspace之外的所有文件
rm -rf `ls | grep -vE "^jobs$|^secret.key$|^secret.key.not-so-secret$|^secrets$|^userContent$|^users$|^workspace$"`
rm -rf `ls | grep -vE "^jobs$|^secret.key$|^secret.key.not-so-secret$|^secrets$|^userContent$|^users$|^workspace$|^plugins$"`
````
5. 升级[jenkins镜像](registry.cn-beijing.aliyuncs.com/kubesphereio/ks-jenkins:2.249.1)为`jenkins/jenkins:2.354-centos7-jdk8`,然后清理挂载目录(按第4个问题的命令清理),出现如下错误
```bash
2022-08-25 06:29:48.180+0000 [id=10] WARNING h.i.i.InstallUncaughtExceptionHandler#handleException: Caught unhandled exception with ID 077a9ea8-f2e2-4590-a73a-477279c34ccb
hudson.security.AccessDeniedException3: anonymous is missing the Overall/Read permission
at hudson.security.ACL.checkPermission(ACL.java:80)解决:
参考
Android-osmdroid
参考工具
github: osmdroid/osmdroid
compile 'org.osmdroid:osmdroid-android:<VERSION>'
离线地图制作工具: Mobile Atlas Creator
离线地图工具类SampleOfflineOnly.java
操作步骤
离线地图制作
- 打开Mobile Atlas Creator工具
- 新建地图册(可选Osmdroid ZIP/SQLite/GEMF)
- 选择地图源
- 勾选图片转换,设置图块格式(重要,要和代码的设置一致)
- 设置缩放比例
- 地图上框选区域
- 在当前地图册点击添加选择区域
- 最后开始点击下载地图册
- 得到一个压缩文件,存储备用
离线地图自定义地图源(geoserver)
在Mobile Atlas Creator工具目录的
mapsources
目录添加地图源配置文件geoserver地图地图源配置文件
geoserver_maps.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customWmsMapSource>
<name>My Geoserver WMS</name>
<minZoom>0</minZoom>
<maxZoom>18</maxZoom>
<tileType>PNG</tileType>
<version>1.1.1</version>
<!-- 图层名字hws(工作空间):china_net(图层名字) -->
<layers>hws:china_net</layers>
<!-- hws替换为自己的工作区间,ip端口替换自己服务器的,其他不变 -->
<url>http://192.168.1.230:8082/geoserver/hws/wms?service=WMS&</url>
<!-- 投影坐标系 -->
<coordinatesystem>EPSG:4326</coordinatesystem>
<aditionalparameters></aditionalparameters>
<backgroundColor>#000000</backgroundColor>
</customWmsMapSource>多图层配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customMultiLayerMapSource>
<name>多图层自定义</name>
<tileType>png</tileType>
<backgroundColor>#000000</backgroundColor>
<!-- 0~1由透明到不透明,1.0是设置对底层的图层,0.5是设置底层上一层图层,以此类推n图层以此设置即可-->
<layersAlpha>1.0 1.0 0.5 1.0</layersAlpha>
<layers>
<customMapSource>
<name>Google 卫星图</name>
<minZoom>0</minZoom>
<maxZoom>20</maxZoom>
<tileType>PNG</tileType>
<tileUpdate>None</tileUpdate>
<url>http://mt0.google.cn/vt/lyrs=s@124&hl=zh-CN&gl=CN&src=app&x={$x}&s=&y={$y}&z={$z}&s=Galileo</url>
<backgroundColor>#000000</backgroundColor>
</customMapSource>
<customMapSource>
<name>Google 地名图</name>
<minZoom>0</minZoom>
<maxZoom>20</maxZoom>
<tileType>PNG</tileType>
<tileUpdate>None</tileUpdate>
<url>http://mt0.google.cn/vt/imgtp=png32&lyrs=h@207000000&hl=zh-CN&gl=CN&src=app&x={$x}&y={$y}&z={$z}&s=Galil</url>
</customMapSource>
<customWmsMapSource>
<name>林班界</name>
<minZoom>0</minZoom>
<maxZoom>20</maxZoom>
<tileType>PNG</tileType>
<tileUpdate>None</tileUpdate>
<layers>hws:linbanjie</layers>
<url>http://192.168.1.230:8082/geoserver/hws/wms?service=WMS&transparent=TRUE&</url>
<!-- 投影坐标系 -->
<coordinatesystem>EPSG:4326</coordinatesystem>
<aditionalparameters></aditionalparameters>
</customWmsMapSource>
<customWmsMapSource>
<name>巡护路线</name>
<minZoom>0</minZoom>
<maxZoom>20</maxZoom>
<tileType>PNG</tileType>
<tileUpdate>None</tileUpdate>
<!-- 图层名字hws(工作空间):china_net(图层名字) -->
<layers>hws:xunhuluxian</layers>
<!-- hws替换为自己的工作区间,ip端口替换自己服务器的,其他不变 -->
<!-- 多参数,每个参数用&分开-->
<!-- 背景设置透明transparent=TRUE-->
<url>http://192.168.1.230:8082/geoserver/hws/wms?service=WMS&transparent=TRUE&</url>
</customWmsMapSource>
</layers>
</customMultiLayerMapSource>
离线地图自定义地图源(google地图)
在Mobile Atlas Creator工具目录的
mapsources
目录添加地图源配置文件google地图地图源配置文件
google_maps.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customMultiLayerMapSource>
<name>Google 卫星</name>
<tileType>PNG</tileType>
<layers>
<customMapSource>
<name>Google 卫星图</name>
<minZoom>0</minZoom>
<maxZoom>20</maxZoom>
<tileType>PNG</tileType>
<tileUpdate>None</tileUpdate>
<url>http://mt0.google.cn/vt/lyrs=s@124&hl=zh-CN&gl=CN&src=app&x={$x}&s=&y={$y}&z={$z}&s=Galileo</url>
<backgroundColor>#000000</backgroundColor>
</customMapSource>
<customMapSource>
<name>Google 地名图</name>
<minZoom>0</minZoom>
<maxZoom>20</maxZoom>
<tileType>PNG</tileType>
<tileUpdate>None</tileUpdate>
<url>http://mt0.google.cn/vt/imgtp=png32&lyrs=h@207000000&hl=zh-CN&gl=CN&src=app&x={$x}&y={$y}&z={$z}&s=Galil</url>
</customMapSource>
</layers>
</customMultiLayerMapSource>地图源文件xml的设置搜索
Mobile Atlas Creator自定义地图源
IPad 離線地圖:「Mobile Atlas Creator + 地圖加加」,讓google map成為好用的離線地圖!!
Android代码设置
导包
compile 'org.osmdroid:osmdroid-android:<VERSION>'
手动设置离线地图的文件
1
2
3
4
5
6
7//路径压缩包的路径放在存储目录下/osmdroid/Google Maps(世界墨卡托).zip这个是刚刚用工具制作得到的压缩文件
String path=Environment.getExternalStorageDirectory().getAbsolutePath() + "/osmdroid/"+"Google Maps(世界墨卡托).zip";
//设置为离线工作模式。路径一定要对,而且只支持 ZIP/SQLite/GEMF
mapView.setTileProvider(new OfflineTileProvider(new SimpleRegisterReceiver(this),new File[]{new File(path)}));
//这里Google Map为压缩文件的第一层目录名,一定要一致,.png.tile为最内层目录的文件后缀名一点定要一致,一般是png,这里比较特殊
mapView.setTileSource(new XYTileSource("Google Map", 7, 16,
256, ".png.tile", null));上面那步基本就可以解析了,官方使用SampleOfflineOnly.java做自动解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49//设置离线地图的路径
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/osmdroid/");
if (f.exists()) { //判断目录是否存在
File[] list = f.listFiles(); //得到该目录下的文件
if (list != null) {
for (int i = 0; i < list.length; i++) { //遍历的得到的所有目录和文件
if (list[i].isDirectory()) { //目录跳过
continue;
}
String name = list[i].getName().toLowerCase();
if (!name.contains(".")) { //没有后缀跳过
continue; //skip files without an extension
}
name = name.substring(name.lastIndexOf(".") + 1); //得到后缀名
if (name.length() == 0) {
continue;
}
if (ArchiveFileFactory.isFileExtensionRegistered(name)) { //后缀名是否是ZIP/SQLite/GEMF其中一个
try {
OfflineTileProvider tileProvider = new OfflineTileProvider(new SimpleRegisterReceiver(this),
new File[]{list[i]}); //如果是把该文件作为离线地图的提供者
mapView.setTileProvider(tileProvider); // <重要>
String source = "";
IArchiveFile[] archives = tileProvider.getArchives();
if (archives.length > 0) {
Set<String> tileSources = archives[0].getTileSources();
if (!tileSources.isEmpty()) {
source = tileSources.iterator().next(); //活动压缩文件第一级目录的目录名
//自定义设置 <重要> ,其中文件后缀名要和压缩文件内的后缀一致
this.mapView.setTileSource(new FileBasedTileSource(source,0, 18, 256, ".png", null));
// this.mapView.setTileSource(FileBasedTileSource.getSource(source)); //默认设置
} else {
this.mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
}
} else {
this.mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
}
this.mapView.invalidate();
return;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
Toast.makeText(this, f.getAbsolutePath() + " did not have any files I can open! Try using MOBAC", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, f.getAbsolutePath() + " dir not found!", Toast.LENGTH_SHORT).show();
}
常见问题
- 当mobac配置多图层时,geoserver wms不加
transparent=TRUE&
会有白色背景,设置透明度会导致最底层的地图上覆盖了一层半透明的白色,导致看不起低图 - mobac加载geoserver gwc连接,如果图层只有一部分,会导致Google map在图层之外的也加载不出来
参考
Java-Type
type泛型解析
1 | Map<String, Integer> map; |
参考:
DB-Realm-Base
简介
全平台通用数据库
- 特点自带通知
- 实体类方式
使用
在project中的build.gradle添加
1
2
3dependencies {
classpath "io.realm:realm-gradle-plugin:5.1.0"
}在model中的build.gradle添加
1
apply plugin: 'realm-android'
新建实体类,两种方式
方式一
1
2
3
4
5@RealmClass
public class TestEntiy implements RealmModel {
private Long id;
......
}方式二
1
2
3
4public class TestEntiy extends RealmModel {
private Long id;
......
}在application中初始化realm
1
2
3
4
5
6
7Realm.init(context); //数据库初始化
RealmConfiguration config = new RealmConfiguration.Builder().name("mulun.realm").build();
Realm.setDefaultConfiguration(config); //设置配置,数据库文件名为mulun.realm
//测试
Realm realm = Realm.getDefaultInstance(); //获取数据库实例
Log.i("MyApplication","数据库路径为:"+realm.getPath()); //打印路径
realm.close(); //用完需要关闭实例在data/data/包名/file目录下可以找到数据库文件
mulun.realm
该文件可以通过
Realm Studio
打开
进阶
数据库插入/删除数据
1 | Realm realm = Realm.getDefaultInstance(); //获取数据库实例 |
另一种操作方式
1 | Realm realm = Realm.getDefaultInstance(); //获取数据库实例 |
Docker-Install-Jenkins
简介
github文档:jenkinsci/docker
Docker hub:jenkins/jenkins
安装
脚本文件https://github.com/xuanfong1/config/blob/master/dockerStack/stack-jenkins.yml
创建挂载目录
启动提示:
1 | touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied |
解决:执行chown -R 1000:1000 /dockerdata/v-jenkins/jenkins_home
改变用户组为1000 用户1000
jenkins 之docker插件
docker-build-step 构建步骤使用docker命令
CloudBees Docker Build and Publish镜像构建以及推送仓库
Docker 远程连接docker进行代理构建
Docker API提供其他插件docker服务api
CloudBees Docker Custom Build Environment构建镜像或从仓库拉去镜像
https://github.com/boxboat/jenkins-demo
错误处理
连接错误,解决添加挂在卷
"/var/run/docker.sock:/var/run/docker.sock"
1
2
3Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
script returned exit code 1连接没权限,解决
1
2
3Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.35/build?buildargs=%7B%7D&cachefrom=%5B%5D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&labels=%7B%7D&memory=0&memswap=0&networkmode=default&rm=1&session=6ec5bc5a7afd427649abb0a03b733c9586dd9271474c89359e31a3910ed971e8&shmsize=0&t=e5e2d0e18760db6972a9c42a9a81653e633ff131&target=&ulimits=null: dial unix /var/run/docker.sock: connect: permission denied
script returned exit code 1执行
sudo ls -la /var/run/docker.sock
1
srw-rw----. 1 root docker 0 5月 15 16:36 /var/run/docker.sock
--group-add=$(stat -c %g /var/run/docker.sock)
sudo usermod -a -G docker jenkins
解决方案
方案一
改变socke所属的用户组
用root用户进入jenkins容器
执行
chown :jenkins /var/run/docker.sock
1
2
3
4
5
6
7
8
9
10-------------宿主机------------------------------
[root@worker ~]# ls -la /var/run/docker.sock
srw-rw----. 1 root docker 0 6月 6 16:58 /var/run/docker.sock
执行后
[root@worker ~]# ls -la /var/run/docker.sock
srw-rw----. 1 root 1000 0 6月 6 16:58 /var/run/docker.sock
------------------jenkins容器---------------------
srw-rw---- 1 root 994 0 Jun 6 08:58 var/run/docker.sock
执行后
srw-rw---- 1 root jenkins 0 Jun 6 08:58 var/run/docker.sockcat /etc/group
查看用户组id自我理解:
这里通过挂载卷的形式共享/var/run/docker.sock套接字,但是默认套接字属于root docker组,这里docker的组id为994,但是容器内没有994的组,所以直接显示994,最后执行这个
chown :jenkins /var/run/docker.sock
之后把组更改为乐jenkins组,但是默认宿主机是没有jenkins组,所以直接显示jenkins的id 1000,这里直接修改为jenkins用户组,虽然可以解决权限问题,不知道会不会影响其他的使用该sock套接字(隐患)完善思路:
新建个jenkins组
添加docker用户到jenkins组
但是发现
宿主机
id docker
没有docker用户且docker组没有任何用户,因此可以放心更改组,所以要不要新建组待考虑
1
2
3
4cat /etc/group #查看组信息
cgred:x:995:
docker:x:994:jenkins
#组名:口令(默认空/*):组标识号(gid):组内用户列表方案二
自我新思路
宿主机创建个jenkins用户组指定id1000
宿主机执行
useradd -u 1000 jenkins
然后执行
sudo usermod -a -G docker jenkins
失败,没有权限
方案三(未实验)
root用户可以访问docker,需要重写dockerfile
1
2FROM <base-image>
USER root隐患:不知到用root用户登陆会不会影响jenkins的一些功能
方案四(未实验)
修改
groupadd -g 994 docker
,找不到命令然后执行
usermod -a -G docker jenkins
此法每次重启容器都会丢失配置,虽然可以通过挂载目录形式保存设置,太麻烦。
Jenkins 第一次打开,一直显示启动中
解决:
修改jenkins_home/updates/default.json
把 “connectionCheckUrl”:”http://www.google.com/" 改为 “connectionCheckUrl”:”http://www.baidu.com/"
centos 安装jenkins,需要jdk8
1 | sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo |
JavaEE-shiro
简介
Apache Shiro是java的一个安全框架,和Spring Security
比相对简单,功能简单,使用简单,适合小型简单的项目。
功能
- Authentication:身份认证/登陆,验证用户身份
- Authorization:授权,权限验证,验证已认证的用户是否拥有某个权限
- session manager:会话管理
- cryptography:加密
- web support:web支持
- caching:缓存
- concurrency:多线程并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
- testing:测试支持
- run as:运行一个用户假装另一个用户的身份进行登陆
- remember me:记住我密码功能
原理
graph LR a[object/用户]-->b[SecurityManager/shiro] b-->c[Realm/数据源]
简单体验登陆
在gradle引入依赖
compile group: 'org.apache.shiro', name: 'shiro-core', version: '1.4.0'
在目录
resources
下新建一个shiro.ini
文件1
2
3
4
5
6
7
8
9
10
11# users 标签下面格式为
# 用户名 = 密码,角色1,角色2,....,角色N
[users]
root = secret, admin
guest = guest, guest
test = 123456,test
# roldes 角色标签下面格式为
# 角色 = 权限1,权限2, ....权限N
[roles]
admin = *创建登陆方法,
IniSecurityManagerFactory
该方法在1.4已经过期了,用下面的方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:shiro.ini"); //此方法过期
IniRealm iniRealm=new IniRealm("classpath:shiro.ini"); //读取shiro配置文件
DefaultSecurityManager securityManager=new DefaultSecurityManager(iniRealm);
SecurityUtils.setSecurityManager(securityManager);
Subject currentUser=SecurityUtils.getSubject();
if (!currentUser.isAuthenticated()){
UsernamePasswordToken token=new UsernamePasswordToken("admin","1");
token.setRememberMe(true);
try {
currentUser.login(token);
}catch (UnknownAccountException una){
System.out.print("用户名不存在"+una.getMessage());
}catch (IncorrectCredentialsException ice){
System.out.print("无效的认证"+ice.getMessage());
}catch (LockedAccountException lae){
System.out.print("你的账户被锁定"+lae.getMessage());
}catch (AuthenticationException ae){
System.out.print("未知错误"+ae.getMessage());
}
}
shiro名词概念解释
- subject :当前操作的用户
- SecurityManager :shiro框架核心,内部组件管理
- realm : 连接桥梁,用于和用户数据,权限数据连接(来源文件、数据库)
xml配置
1 | <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> |
数据库表设计:
参考
Dubbo-Gradle-Config
配置方式一xml
在resources目录dubbo-provider.xml
配置
1 | <?xml version="1.0" encoding="UTF-8"?> |
需要在dubbo启动器指向xml名字
1 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( |
配置方式二dubbo.properties
注:配置文件名字是固定的
1 | dubbo.registry.address=zookeeper://10.14.1.7:2181 |
配置方式三jvm
注:gradle application task run启动vm设置无效
1 | -Ddubbo.registry.address=zookeeper://10.14.1.7:2181 |
覆盖策略
JVM>XML>Properties其中jvm优先级最高
Dubbo-Gradle-Build
源码:https://github.com/xuanfong1/DubboLearning
新建目录
mkdir DubboLearning
,然后cd Dubbolearning
进去之后执行gradle init
初始化gradle项目新建三个子项目目录
mkdir library,provider,consumer
分别为公共依赖项目、提供者、消费者复制build.gradle到三个子项目目录
分别为三个子项目创建目录
mkdir -p src/main/java,src/test/java,src/main/resources
修改顶级项目目录的setting.gradle添加三个子项目
1
2
3include 'library'
inclede 'provider'
inclede 'consumer'复制项目helloworld的源码到项目目录
然后修改顶级项目目录build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29plugins {
id "org.springframework.boot" version "2.0.1.RELEASE"
}
allprojects {
repositories {
jcenter() //将jcenter仓库配置到所有项目
}
}
subprojects {
version = '1.0' //设置版本号
}
configure(subprojects.findAll {it.name == 'provider' || it.name == 'consumer'} ) {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: "org.springframework.boot"
apply plugin: 'io.spring.dependency-management'
group = 'exxk.dubbo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile group: 'com.alibaba', name: 'dubbo', version: '2.6.1'
testCompile('org.springframework.boot:spring-boot-starter-test')
compile project(':library')
}
}
额外
https://plugins.gradle.org/plugin/org.springframework.boot
1 | //低版本,动态 |
报错:
1 | Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/curator/RetryPolicy |
解决:添加依赖compile group: 'org.apache.curator', name: 'curator-framework', version: '4.0.1'
Gradle构建java库
gradle init --type <name>
其中name可选
- java-application
- java-library
- scala-library
- groovy-library
- basic
build java-library
This guide walks you through the process of using Gradle’s Build Init plugin to produce a JVM library which is suitable for consumption by other JVM libraries and applications.
本指南引导您完成使用Gradle的Build Init插件生成适合其他JVM库和应用程序使用的JVM库的过程。
1 | mkdir demo-java-lib #创建项目目录 |
build.gradle
解读
1 | plugins { |
执行./gradew build
第一次构建会下载依赖jar包比较慢,下载到目录~/.gradle/wrapper/dists
,编译完成后生成
- build/reports/tests/test/index.html 测试报告
- build/libs/building-java-libraries.jar 编译生成的jar
jar tf build/libs/building-java-libraries.jar
命令查看jar包内容,其中-f
指定jar文件名,-t
列出包的内容
修改build.gradle
文件在文件里添加版本好version = '0.1.0'
,结果会修改打包的名称为build/libs/demo-java-lib-0.1.0.jar
修改build.gradle
文件在文件里添加jar
task任务
1 | jar { |
会修改build/libs/building-java-libraries-0.1.0.jar/META-INF/MANIFEST.MF
jar包文件的内容为
1 | Manifest-Version: 1.0 |
java-library内置支持javadoc,执行./gradlew javadoc
会生成/build/docs/javadoc/index.html
文档
build java-application
java项目和library项目一样,只是多了tasks任务 run