近期Atlassian公司发布公告 Cloud-first 战略转型 : Journey-to-cloud

Atlassian产品主要有下面三种形态:

Type 简介 后续影响
Server 1. 一次性付费(授权期间可以版本升级,到期后服务还可以正常使用)
2. 公司团队进行运维,可自由选择托管内部服务器或者云服务器
3. 适合对数据托管有本地化需求 的 中小型公司使用
1. 已经购买正版授权的,正常使用
2. 还没有购买正版授权的,需要在2021/2/2之前下单购买
3. 2024/2/2后官方不在维护Server产品
Data Center 1. 订阅制(年付)
2. 公司团队进行运维,可自由选择托管内部服务器或者云服务器
3. 相较于Server版本,增加了高可用 和 CDN 原生支持
4. 适合对数据托管有本地化需求 的 跨国多中心研发团队使用
1. 官方会一直维护更新Data Center产品
2. 2021/2/2后会调价
Cloud 1. 订阅制(年付/月付)
2. Atlassian公司进行运维,服务搭建在Atlassian公司云服务器
3. 适合对数据托管没有本地化需求 的 各类 公司使用
4. 目前没有使用国内的云服务器,所以国内网络访问速度和稳定性待考察
1. 官方战略龙头产品,放心使用

logo

受影响的产品:

  • Jira software
  • Jira Core
  • Confluence
  • Bitbucket
  • Bamboo
  • Crowd
  • Jira Service Desk
  • Atlassian apps
  • Marketplace apps

Comment and share

背景

原生Centos7系统的yum源自带git版本是1.8.3.1。

这个版本诞生于:10-Jun-2013。

很多新特性都不支持,为了更好的使用git,我们需要进行版本升级。

源码编译安装

  1. 安装相关依赖
    1
    2
    # yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel asciidoc
    # yum install gcc perl-ExtUtils-MakeMaker
  2. 卸载当前git
    1
    # yum remove git
  3. 下载新版本源码包
    1
    2
    3
    4
    官方仓库地址:https://mirrors.edge.kernel.org/pub/software/scm/git/
    当前最新版本:git-2.28.0.tar.xz 27-Jul-2020

    # wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.28.0.tar.xz
  4. 源码编译安装
    1
    2
    3
    4
    5
    6
    7
    8
    # tar -xvf git-2.28.0.tar.xz
    # cd git-2.28.0/
    # which openssl 获取本机openssl路径,当前机器/usr/bin/openssl
    # ./configure --with-openssl=/usr/bin/openssl
    # make prefix=/usr/local/git all
    # make prefix=/usr/local/git install
    # echo "export PATH=$PATH:/usr/local/git/bin" >> /etc/profile
    # source /etc/profile

Comment and share

系统软件环境

系统软件 版本
Jenkins 2.150.2
Slave Windows 10

问题描述

部分 Windows slave job 执行时间较长,日志分析发现不是Job脚本更新导致,而是因为Jenkins退出卡住。
日志分析:案例
具体任务在13:41就已经执行完成,但是Jenkins在13:51才退出返回结果。
也就是说整整卡住了10分钟,必须要解决。

原因分析

Jenkins 在 2.14 版本引入了 killSoftly 特性,出发点是想更加优雅的结束进程。
但是导致了 Windows slave上的 batch 脚本 执行完成 返回结果卡住(时间不确定)的情况。
Linux slave上的 shell 脚本执行退出没有发现此问题。

1
2
3
// Firstly try to kill the root process gracefully, then do a forcekill if it does not help (algorithm is described in JENKINS-17116)

killSoftly();

解决方法

可以通过 在Windows slave连接master机器的时候 增加 这个参数 -DSoftKillWaitSeconds=0 来解决。

1
2
3
# Run from agent command line:

java -Xrs -DSoftKillWaitSeconds=0 -jar agent.jar -jnlpUrl ...

使用上述命令重新连接 Master - Slave 后,可以在Slave系统信息界面看到参数生效了。
Slave信息

参考链接

https://issues.jenkins-ci.org/browse/JENKINS-55106
https://stackoverflow.com/questions/54039226/jenkins-hangs-between-build-and-post-build

Comment and share

背景

第三方客户审厂过程中,对公司现有流程管理方法工具有些改进建议。
其中有一条是:软件映像文件的完整性检验为MD5值,校验码和软件包一起发布,建议采用其它安全性更好的校验算法。

方案调研

参考链接: 为什么MD5不能用于存储密码

MD5 是一种摘要算法,我们也可以叫它哈希函数,哈希函数可以将无限键值空间中的所有键都均匀地映射到一个指定大小的键值空间中。一个好的摘要算法能够帮助我们保证文件的完整性,避免攻击者的恶意篡改。
作为一个 1992 年第一次被公开的算法,到今天为止已经被发现了一些致命的漏洞。在任何场景下,我们都应该避免MD5的使用,可以选择更好的摘要算法替代 MD5,例如 SHA256、SHA512。

改进方案

  • 保留现有的md5校验文件(部分客户还在使用)
  • 同时增加SHA256校验文件

基础命令使用

  1. SHA256
    • 生成XXX文件sha256值:
      1
      2
      3
      sha256sum XXX > XXX.sha256

      [root@wangweilong wwl]# sha256sum clean_virus.sh > clean_virus.sh.sha256
    • 追加YYY文件到已有sha256文件:
      1
      2
      3
      sha256sum YYY >> XXX.sha256

      [root@wangweilong wwl]# sha256sum install.log >> clean_virus.sh.sha256
    • 生成的sha256文件内容:
      1
      2
      3
      4
      [root@wangweilong wwl]# cat clean_virus.sh.sha256

      799750ecaf018307e3f3a5b69c69d28635bf047472e99c85f094ef210deb8ac9 clean_virus.sh
      328de949506461ffb371cb2e951d25aadb9e94d7c3038bb08aebce42cd8b84ee install.log
    • 校验方法:
      1
      2
      3
      4
      5
      6
      下载文件和对应的md5值文件到同一目录下,执行 sha256sum -c XXX.sha256 命令

      [root@wangweilong test]# sha256sum -c clean_virus.sh.sha256

      clean_virus.sh: OK
      install.log: OK

  1. MD5
    • 生成XXX文件md5值

      1
      2
      3
      md5sum XXX > XXX.md5

      [root@wangweilong wwl]# md5sum clean_virus.sh > clean_virus.sh.md5
    • 追加YYY文件到已有md5文件

      1
      2
      3
      md5sum YYY >> XXX.md5

      [root@wangweilong wwl]# md5sum install.log >> clean_virus.sh.md5
    • 生成的md5文件内容

      1
      2
      3
      4
      [root@p5-centos6-wangweilong wwl]# cat clean_virus.sh.md5

      7840489fe303c097fb142a982f9f41e7 clean_virus.sh
      16c04079cc2cda26cbab5cfa801df6c6 install.log
    • 校验方法

      1
      2
      3
      4
      5
      6
      7
      8
      下载文件和对应的md5值文件到同一目录下,执行md5sum -c XXX.md5 命令
      为了更好的展示,我修改了install.log文件的内容

      [root@wangweilong test]# md5sum -c clean_virus.sh.md5

      clean_virus.sh: OK
      install.log: FAILED
      md5sum: WARNING: 1 of 2 computed checksums did NOT match

Comment and share

Atlassian公司简介:

官网: https://www.atlassian.com
Atlassian, inspired by the Greek Titan. list on the NASDAQ under TEAM 2015.
Mission: Move work forward. Atlassian helps teams work smarter and faster, together.


主要产品:

产品名称 简介 备注
Jira Project and issue tracking 项目管理系统
Confluence Document collaboration 知识库系统
Trello Collaborate visually on any project 简单的团队协作系统
适合个人或者小团队使用
Bitbucket Git code management 代码库托管系统
支持权限管理/code review等等
类比Github
Bamboo Integration and release management 自动化系统
类比Jenkins
Sourcetree Git and Mercurial desktop client git客户端
Fisheye Search, monitor, and track across SVN, Git, and Perforce repositories 代码库查询展示系统
支持多种代码库
Crucible Find bugs and improve code quality through peer code review code review系统
类比Phabricator

产品形态

类型 简介 优点 缺点 适用场景 付款策略
Cloud ATLASSIAN公司搭建运维云服务 1.开箱即用
2.运维容灾由ATLASSIAN公司保障
3.新版本升级支持
4.日常使用问题支持
1. 国内访问速度慢
2. 数据托管在cloud
1.快速使用
2.多地点使用
3.运维能力一般
per year
Server 公司自行搭建运维服务 1.自行定制配置搭建
2.数据信息存储在自家服务器上
3.访问速度快
自行负责运维(服务/网络) 1.数据保密/安全要求较高
2.运维能力较强团队
one-time payment
服务可以一直使用
包含12个月内的新版本升级支持
如果12个月后还想升级版本的话,需要重新付费
Data Center 公司自行搭建运维服务
官方提供扩展数据/服务容灾支持
1.数据多节点存储
2.负载均衡
3.集群支持
价格太贵了 1.大中型企业级用户(500+)
2.容灾安全/负载均衡要求较高
3.跨多地区团队
per year

工具链选型

  1. 项目管理系统: Jira Server
  2. 公司知识库系统: Confluence Server
  3. 公司代码库: Bitbucket/Git(code review)
  4. 自动化平台: Jenkins (Bamboo正在内部试用调研)

选型思路

0.为什么是Jira Server?

  • 公司项目研发团队在中国,Cloud访问速度慢;
  • 公司现有研发体量不需要过度支持,所以不考虑Data Center;
  • 运维团队比较强力,可以做到服务器高可用支持;
  • IOS/Android 客户端支持;
  • 流程/字段定制功能强大,项目支持方便。

1.为什么是Confluence Server?

  • 和Jira打通非常方便,联动性很好;
  • 系统自带的模版页面非常适合特定场景使用;
  • 易用性很好,学习成本很低;
  • 多人协同编辑可视化很好;
  • IOS/Android 客户端支持

2.为什么是Bitbucket Server?

  • 原有的Gerrit版本比较老,易用性不好;
  • Gitlab / Bitbucket 都可以满足团队代码托管 / code review / 系统集成的需要;
  • 选择 Bitbucket 主要是和Jira && Confluence原生打通非常方便,联动性很好;
  • 源代码是公司核心资产,从安全性考虑,暂时不准备开放公网访问。

3.为什么是Jenkins?

  • 已经使用Jenkins很长时间了,团队人员比较熟悉;
  • 通过二次开发,Jenkins能满足当前项目使用;
  • Bamboo 在Jira && Bitbucket联动性上会比Jenkins好;
  • Bamboo是根据挂载的Remote agents数量进行收费,Jenkins是免费的;
  • 因为项目特殊性,需要用到多Slave挂载,从成本角度考虑还是使用Jenkins更适合。

Comment and share

参考链接:

背景:

搭建了Openldap维护公司域账户信息,Gerrit用户验证接入了LDAP。
gerrit.config配置如下(信息请更新为各自公司节点):

1
2
3
4
5
[ldap]
server = ldap://ldap.example.com
username = ldapuser
accountBase = ou=people,dc=example,dc=com
groupBase = ou=groups,dc=example,dc=com

业务需求:

公司特定合作伙伴 有 访问代码库 进行 联合开发的需求。

方案设计:

  1. 在现有LDAP节点的基础上,增加一个ou(custom),用来维护合作伙伴账号;
  2. 同步 这个ou(custom)的人员到Gerrit上。

配置Gerrit支持多ou user信息:

根据Gerrit官方文档:

1
2
3
ldap.accountBase
Root of the tree containing all user accounts. This is typically of the form ou=people,dc=example,dc=com.
This setting may be added multiple times to specify more than one root.

我们调整gerrit.config配置如下:

1
2
3
4
5
6
[ldap]
server = ldap://ldap.example.com
username = ldapuser
accountBase = ou=people,dc=example,dc=com
accountBase = ou=custom,dc=example,dc=com
groupBase = ou=groups,dc=example,dc=com

然后重启Gerrit后,custom里面的人员也可以登录Gerrit了。


配置Gerrit支持多group信息:

方法和上面同步多个ou user信息相似,增加ldap.groupBase行即可。
根据Gerrit官方文档:

1
2
3
ldap.groupBase
Root of the tree containing all group objects. This is typically of the form ou=groups,dc=example,dc=com.
This setting may be added multiple times to specify more than one root.

关于LDAP group信息:

一般系统接入LDAP做账户验证,只需同步LDAP的user信息,不直接使用LDAP的group信息。
各个系统自行创建系统组进行人员权限管理,这样更加灵活。
同时,也不建议LDAP里面维护太多group,更加推荐LDAP轻量化使用。

Comment and share

Git tips two

in SCM

软件版本:

1
git version 2.23.0

使用http/https协议代码库地址,有时会出现不能存储密码,每次交互操作都需要输入帐户密码情况:

1
2
3
记住密码(默认15分钟):git config --global credential.helper cache
自己定义时间(一小时后失效):git config credential.helper 'cache --timeout=3600'
永久存储密码:git config --global credential.helper store

行结束符处理:

OS Line Endings Comments
Windows CRLF 每行结尾是 <换行><回车 > ,即 \n\r
Mac OS X LF 每行结尾只有 <换行> ,即 \n
Unix/Linux LF 每行结尾只有 <换行> ,即 \n
Classic macOS CR 每行结尾是 <回车>,即 \r
1
2
3
4
5
6
7
8
9
10
11
排除老Mac系统不讨论,项目组如果不是全Windows环境开发/部署的话,还是要自动处理下行结束符。

# Windows用户执行下面配置命令:
$ git config --global core.autocrlf true # 在提交时自动地把行结束符CRLF转换成LF,而在签出代码时把LF转换成CRLF

# Linux 和 Mac用户执行下面配置命令:(预防代码库已经有CRLF结束符的代码)
$ git config --global core.autocrlf input # 在提交时把CRLF转换成LF,签出时不转换

# 默认配置:
$ git config --global core.autocrlf false # 提交和签出时都不对代码行结束符做转换

Comment and share

参考链接:


场景1:

最新的一个提交版本里面新增了敏感、较大、无意义的文件,需要进行清理。
1
2
3
4
5
6
7
8
9
10
11
1. 删除文件
$ git rm --cached ${文件绝对地址}
2. 增加到上述文件到 .gitignore
$ vim .gitignore
3. 修复最新提交版本
$ git commit --amend
4. 推送新版本到远端仓库
如果刚才版本已经推送到远端仓库:
$ git push -f
如果刚才版本只是在本地仓库:
$ git push

场景2:

历史版本里面存在敏感、较大、无意义的文件,需要进行清理。

使用 git filter-branch

git 原生提供的命令,如果没有的话,请先升级机器git版本。

  • 原理:
    扫描代码库所有版本
    如果某个版本里面发现了指定的文件OR目录:
    如果此版本包含要清理的文件OR目录 和 其它变更的话,对此版本进行删除指定文件OR目录(保留其它变更),并生成新的版本。同时后面的版本会变基到新版本。
    如果此版本只包含要清理的文件OR目录变更的话,那么此版本会被清除。同时后面的版本会变基到上一个版本。
    如果版本没有包含指定文件OR目录,那么继续遍历。
  • PS:
    1. 如果代码库历史比较多 OR 涉及到指定文件OR目录的版本比较多,那么命令执行会比较慢。
    2. 一般会导致代码库版本树变化,对于涉及开发同学,建议开始前提交本地修改变更到远端仓库,完成后本机重新clone代码库进行开发。
    3. 一般都在本地仓库根目录执行
    4. 执行命令后历史版本里面已经清理了文件, 但是我们的本地仓库里面仍然保留了这些objects, 等待垃圾回收(GC), 如果想立即回收本地仓库空间可以执行 git gc –prune=now.
1
2
3
4
5
6
7
8
9
10
1. 执行命令
$ git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch ${要清理的文件OR目录的绝对地址}' --prune-empty --tag-name-filter cat -- --all
2. 增加到上述文件OR目录到 .gitignore
$ vim .gitignore
3. 推送新版本到远端仓库
$ git push -f --all
$ git push -f --tags
4. 清理本地仓库残留的git objects
$ git reflog expire --expire=now --all
$ git gc --prune=now

使用 bfg-repo-cleaner

Roberto Tyley使用Scala语言写了 bfg-repo-cleaner工具。
可以简单理解为一个轻量级的 git filter-branch。
使用比较简单,功能比较强大,只需要下载最新的jar包,然后执行👇命令:

1
2
3
4
# 删除大于50M的文件
$ java -jar bfg.jar --no-blob-protection --strip-blobs-bigger-than 50M
# 删除指定文件
$ java -jar bfg.jar --no-blob-protection --delete-files ${要清理的文件的绝对地址}

PS:
1. bfg-repo-cleaner 有个protect功能,默认HEAD是受保护的。
受保护的分支最新版本如果涉及需要清理文件,那么并不会成功。
–no-blob-protection 关闭protect功能
–protect-blobs-from ${分支1},${分支2} 增加受保护的分支
2. 建议在本地仓库根目录执行。


场景3:

查找代码库里面较大文件方法:
- 如果当前版本还存在的文件,可以直接du排序来识别;
- 如果当前版本不存在,但是历史中出现过的大文件,可以按照下面步骤来查询。

1
2
1. 显示比较大的pack
$ du -ah .git/objects/pack

logo

1
2
2. 识别object,对输出的第三列信息即文件大小进行排序
$ git verify-pack -v .git/objects/pack/${pack-XXX.pack} | sort -k 3 -n | tail -5

logo

1
2
3. 识别object对应的文件
$ git rev-list --objects --all | grep ${👆获取的object}

logo

Comment and share

参考链接:

背景:

随着公司前端团队的扩大,需要拆分出公司基础模块供其它项目使用,使用Nexus3搭建公司npm私服。

搭建步骤:

1. 创建npm库:

logo
logo
logo
logo

2. 权限配置:

  • 激活 npm Bearer Token Realm
    logo
  • 创建开发权限组对hosted npm私服库读写权限
    logo
    logo
  • 创建dev帐户并加入到开发权限组
    logo
    logo
1
PS: 匿名用户可以下载私服npm包,只有dev组内的帐户才能publish包到hosted私服

使用:

1.配置nexus私服

  • 查看本机私服配置:
    1
    $ npm config get registry
  • 设置本机配置到group私服:
    1
    2
    $ npm config set registry http://${ip}:8081/repository/${npm_group}/
    (写入到本机.npmrc文件)
  • 此时,项目执行npm install即从nexus上面进行下载包

2.配置publish帐户

有👇两种方式

  • Authentication Using Realm and Login
    1
    2
    3
    4
    5
    6
    7
    8
    9
     $ npm login --registry=http://${ip}:8081/repository/${npm_hosted}/


    Username: dev (各位根据上面创建的帐户自行替换)
    Password: ${dev_pass} (各位根据上面创建的密码自行替换)
    Email: (this IS public) XXX@XXX.com (各位根据上面创建的邮箱自行替换)

    Logged in as dev on http://${ip}:8081/repository/${npm_hosted}/.
    (写入到本机.npmrc文件)
  • Authentication Using Basic Auth
    1
    2
    3
    4
    5
    6
    7
    8
    9
     $ echo -n 'dev:${dev_pass}' | openssl base64  (dev帐户密码base64编码)


    本机.npmrc文件里面增加👇行

    email=XXX@XXX.com
    always-auth=true
    _auth=${base64编码后的值}

3.推送npm包到nexus

有👇两种方式

  • 命令行 + 发布路径

    1
    $ npm publish –registry http://${ip}:8081/repository/${npm_hosted}
  • package.json配置发布路径(推荐)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    项目package.json增加👇配置:

    "publishConfig" : {
    "registry" : "http://${ip}:8081/repository/${npm_hosted}/"
    },


    执行👇命令即可
    $ npm publish

Comment and share

localRepository机制:

  • introduction-to-repositories
    The local repository refers to a copy on your own installation that is a cache of the remote downloads, and also contains the temporary build artifacts that you have not yet released.

  • settings.xml配置:

    /path/to/local/repo

  • 使用场景:

    • maven执行编译打包时先进行依赖的下载:
    • 如果项目依赖localRepository中已经存在,那么继续进行编译打包;
    • 如果项目依赖localRepository中不存在,那么先下载依赖到localRepository,然后进行编译打包;

强制更新SNAPSHOT版本依赖:

  • snapshots updatePolicy
    • updatePolicy: This element specifies how often updates should attempt to occur. Maven will compare the local POM’s timestamp (stored in a repository’s maven-metadata file) to the remote. The choices are: always, daily (default), interval:X (where X is an integer in minutes) or never.
  • 👇场景下需要强制更新:
    • 默认snapshot版本依赖localRepository更新是天级的。如果项目联调阶段一天之内多次snapshot依赖更新。

    • 如果项目下载依赖过程中断(常见网络原因),导致localRepository中的文件状态有问题。

      mvn clean package -U

      -U,–update-snapshots
      Forces a check for missing releases and updated snapshots on remote repositories

强制更新RELEASE和SNAPSHOT版本依赖:

  • 👇场景建议使用强制更新:

    • 如果项目下载依赖过程中断(常见网络原因),导致localRepository中的文件状态有问题。
  • 方法:

    • 简单粗暴型:直接清空localRepository,然后执行编译打包重新下载依赖。

    • 推荐精细型:定向删除localRepository中 本次项目涉及依赖,然后重新下载:

      mvn dependency:purge-local-repository

        tells Maven to clear all dependency-artifact files out of the local repository, and optionally re-resolve them.
      

Comment and share

Author's picture

Weilong

    Write something about work-life:

PM


Shenzhen