PouchContainer 开源版本及内部版本一致性实践

为什么要做内外版本一致

对外开源是提升影响力、共建生态的有力手段。在项目对外开源的过程中,首先是将可以开源的部分抽离出来,发布一个“开源版本”,与内部基础设施相关的部分则留在内部版本中。在后续的开发中,开源版本随着社区不断演进,内部版本则随着内部的需求不断迭代。如果没有明确定义内外部版本的边界、代码同步不完全、不及时,将会导致内外版本越走越远,变成两个不相干的项目。

促使我们开始做内外版本一致事情的,主要是以下三点考虑:

  • __降低维护成本: __这也是同步工作的出发点。减少多版本维护的工作负担,也方便团队的交流。
  • __发挥社区的优势: __吸收社区力量是开源的一个重要考虑,让社区的力量真正在内部发挥价值。社区会有一些我们没有考虑到的需求,有集结社区力量的更严格的 review,与 github 集成的强约束 CI 等。
  • __降低功能同步的风险: __在内外部版本不同源的情况下,将外部代码合并进来非常容易冲突。代码模块较多,解决冲突的过程中,一不小心就会引入非预期的修改,而这在合并的过程中,很难发现。

本文将详细说明 PouchContainer 是如何做到内外部版本一致的。

差异梳理及边界定义

PouchContainer 开源已经将近一年了,在内外部版本差异梳理之前,没有人能讲清楚两个版本之间的差异。于是我用 Beyond Compare4 等软件,进行文件级别的比对,一个个找出内外部不同的代码,进而梳理出内外部功能级别的差异。所幸内外部的差异比我想象中的要小。主要有以下几类差异:

  • 对内部老系统的接口兼容
  • 为内部系统开的后门接口
  • 对接内部基础设施的逻辑,如存储,网络
  • bugfix, feature 没有互相同步

前三类差异是集团内针对 PouchContainer 的定制化内容。当然,有一些是目前迫不得已加上的临时逻辑。在后续的发展中,将会改造、下线。第四类的差异,主要原因在于开发者没有版本同步的意识:bugfix 在内部紧急修复之后,没有同步到社区。社区开发者的 bugfix, feature 没有及时同步进内部代码。

在差异梳理出来之后,需要明确内外部的功能边界。能开源的就开源,独有的功能继续保留。抹平非功能性的不一致。

一致性改造

__版本同步的根本还是提升软件的可拓展性__,允许共用一套核心代码,针对不同的业务场景进行定制。所以我们面对的问题不仅是内外部版本的一致问题,应该是三版本、四版本、多版本的一致问题。这也是 PouchContainer 赋能其他业务场景的基础。同样也是开源项目内部使用的必修课 所以,我们做的第二步是通过__插件机制__提升 PouchContainer 的可拓展性。目前我们支持 API, container, daemon, volume,cri 这五种插件。具体见文档

插件的设计旨在提升软件的扩展性,但不允许插件改变原有的工作流程。PouchContainer 提供了对 container, daemon, volume, cri 关键步骤的 hook。以 daemon 插件为例,该插件提供了对启停接口的 hook。插件实现者可以在 daemon 启动前运行一些其他程序,比如 dfget。在 daemon 停止前,做一些清理操作。

// DaemonPlugin defines places where a plugin will be triggered in pouchd lifecycle
type DaemonPlugin interface {
// PreStartHook is invoked by pouch daemon before real start, in this hook user could start dfget proxy or other
// standalone process plugins
PreStartHook() error // PreStopHook is invoked by pouch daemon before daemon process exit, not a promise if daemon is killed, in this
// hook user could stop the process or plugin started by PreStartHook
PreStopHook() error
}

而 API 插件通过将路由表传给插件,允许插件实现者扩展、删除、修改 API。这让接口有了很大的灵活性。

import "github.com/alibaba/pouch/apis/server/types"
// APIPlugin provide the ability to extend PouchContainer HTTP API and change how handler behave.
type APIPlugin interface {
// The default handler of each API would be passed in while starting HTTP server.
// UpdateHandler could register extra HTTP API to PouchContainer server,
// change the behavior of the default handler.
UpdateHandler([]*types.HandlerSpec) []*types.HandlerSpec
}

通过插件化的改造,绝大部分的内部 PouchContainer 定制化逻辑都在插件中实现了。插件单独一个文件目录,在代码合入的时候几乎不会产生冲突。之后将内部插件逻辑和其他差异一个个 commit 到开源分支上。__做到内外部版本的同源。__

稳定性保障

PouchContainer 开源版本代表通用功能,如果外部开发者在通用版本上迭代的新增功能,集团内部用不到,该如何保障外部功能同步到内部之后,不影响内部的现有功能的?

首先内部版本是有一套完整的测试覆盖的,__内部测试在开源测试的基础上还包含针对内部场景的测试__。内部测试通过,我们便认为该版本是符合内部场景要求的,开源版本没有影响内部稳定性的。如果测试不通过,有两个选择,一是重新评估开源通用功能,是否有代码缺陷;二是在内部仓库打补丁。以此来保障开源代码同步至内部后的稳定性。

建立新的秩序

我们先来看看,在这之前的工作流是怎样的。开发者分别在内部仓库和开源仓库提代码,紧急一些的需求会先在内部仓库提 merge request,不那么重要的需求会先在社区提 PR。有人会定期将开源分支 merge 进内部仓库。这里有几个问题,一是内部也有一套测试流程,这套流程可能不像 travisCI 或 circleCI 对接 github 那么方便,有些设计好的测试在内部仓库甚至不会跑。二是没有插件化前,某些功能在内外部有两种不同的实现,这在每次手动 merge 代码的时候几乎都会冲突,解决冲突的过程很容易引入非预期的修改,下次又继续冲突。

git flow 如图

在完成一致性改造之后,我们建立一套规则来保证后续不会再出现版本分离的事情。

  1. 原则上非私有增强,应该先在社区提交 PR,merge 之后通过同步机制进入内部版本
  2. 如果时间紧急,bugfix 先在内部版本上提交。后续 commiter 负责将其 cherry-pick 到社区。社区 review 发现需要继续修改的,将修改另提一个 commit,这样保证 commit 不与内部仓库冲突
  3. 代码同步,由机器人定时提交 merge request 将开源同步至内部
    在 merge 的时候,保证是 fast-forward 的,这样内外部的 commit 是一一对应的,减少冲突。

总结

开源,能帮助项目吸收外部养分,加速项目的演进。在一致性的改造过程中,帮助开发者明确内外部版本的边界,打造同一份核心代码,提升核心代码的可定制化能力,更好地服务于不同的场景。

PouchContainer 开源版本及内部版本一致性实践的更多相关文章

  1. Android 获取手机内部信息,内核版本、基带版本、内部版本等

    TextView text = (TextView) findViewById(R.id.textView1); String phoneInfo = "Product: " + ...

  2. 重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell

    原文地址:https://yq.aliyun.com/articles/694603 本文作者:阿里开源  本文来自云栖社区合作伙伴"阿里系统软件技术",了解相关信息可以关注&qu ...

  3. Apache Flink 1.9重磅发布!首次合并阿里内部版本Blink重要功能

    8月22日,Apache Flink 1.9.0 版本正式发布,这也是阿里内部版本 Blink 合并入 Flink 后的首次版本发布.此次版本更新带来的重大功能包括批处理作业的批式恢复,以及 Tabl ...

  4. Win7盗版提示,屏幕右下角出现 Windows内部版本7601此Windows副本不是正版怎么办

    Windows7 屏幕右下角出现 Windows内部版本7601此Windows副本不是正版 有很多人反应windows7会出现提示"Win7内部版本7600此Windows副本不是正版&q ...

  5. 测试模式 windows2008 内部版本7601

    win server 2008 r2 enterprise 64位系统. 最近手贱,对服务器进行了一下更新,结果傻叉了,这是什么鬼,明明显示已经激活的,但就是有这么一串碍眼的字幕. 电脑右下角居然出现 ...

  6. SQLServer-Version:SQLServer版本对应内部数据库版本号配置表

    ylbtech-SQLServer-Version:SQLServer版本对应内部数据库版本号配置表 1.返回顶部 1. 1.1 查询SQLServer对应的内部数据库版本号select DATABA ...

  7. 开源:Taurus.MVC-Java 版本框架 (支持javax.servlet.*和jakarta.servlet.*双系列,内集成微服务客户端)

    版本说明: 因为之前有了Taurus.MVC-DotNet 版本框架,因此框架标了-Java后缀. .Net  版本: 开源文章:开源:Taurus.MVC-DotNet 版本框架 (支持.NET C ...

  8. Docker技术浅谈:私有化部署的优势以及在顶象内部的应用实践

    顶象全景式业务安全风控体系基于新一代风控体系构建,并采用Docker技术进行私有云和公有云部署.本文主要和大家分享下Docker容器技术和顶象风控系统私有化部署的优势以及Docker容器技术在顶象内部 ...

  9. maven快照版本和发布版本

    在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次.我们知道,maven的依赖管理是基于版本管理的, ...

随机推荐

  1. c# 使用NOPI 操作Excel

    最近项目需要导出Excel,找来找去,微软有自己的Excel组件 using Microsoft.Office.Core;using Microsoft.Office.Interop.Excel;,但 ...

  2. Android SDK中无法安装HAXM installer

    一.原因: 刚搭建好环境,当我想打开Android Studio 自带的模拟器时,出现如下:       /dev/kvm is not found 二.解决步骤: 1.点击File -- Setti ...

  3. Unity3d -- Collider(碰撞器与触发器)

    (2d与3d的Collider可以相互存在,但是无法相互协作,如2d是无法检测3d的,反之,一样) 在目前掌握的情况分析,在Unity中参与碰撞的物体分2大块:1.发起碰撞的物体.2.接收碰撞的物体. ...

  4. Go学习笔记:初识Go语言

    Go语言简介 Go语言是Google(谷歌)公司开发的一款静态型.编译型并自带垃圾回收机制和并发的编程语言. Go语言的风格类似于C语言.其语法在C语言的基础上进行了大幅的简化,去掉了不需要的表达式括 ...

  5. MonkeyTalk使用方法

    1.简单介绍 MonkeyTalk软件测试工具由两部分构成:MonkeyTalk IDE 和 MonkeyTalk Agents MonkeyTalk IDE是Eclipse平台的工具,工能是:对iO ...

  6. forEarch 和 for in

    forEarch 遍历数组,遍历的过程中不能被终止,必须每一个值遍历一遍后才能停下来,for  in遍历对象中的属性 代码: <!DOCTYPE html> <html lang=& ...

  7. JAVA错误:Exception in thread "main" java.lang.NullPointerException

    JAVA错误:Exception in thread "main" java.lang.NullPointerException例如: Exception in thread &q ...

  8. delphi获得文件大小

    大概有这些方法可以获得文件大小 FileSizeByName(需要引用IdGlobal单元) GetFileSize FileSize(不能获得正在使用的文件大小) FileSeek TFileStr ...

  9. 2017-3-8 html基础标签

    <head></head>头标签 <title>页面标签</title> <body>文档的内容可在浏览器中显视的</body> ...

  10. 关于windows下远程连接Linux服务器的方法(CentOs)

    1.服务器端安装VNC 1) 安装vncserver yum install -y tigervnc-server 2) 修改配置 vi /etc/sysconfig/vncservers   最后两 ...