远程办公之ROM/Framework远程开发环境实践

1,225 阅读5分钟

ROM和Framework的远程开发是我们部门很早就在实践的一个开发模式,由于工作环境的缺失,我们不得已在云上工作。在现在这个特殊的时候,远程办公风生水起,我把我们使用的这种远程开发ROM的办法分享给大家,希望对有需要的人有所帮助。以下包括Docker和VS Code的内容,如果不敢兴趣或者觉得太low,可以撤了😏😶。🤥留个建议也好~~~

一个ROM的源码有10GB左右,而编译出来,加上一些中间文件,总共有100GB左右。而我们需要维护20多个这样的ROM。而且编译ROM一般都是采用多线程编译的方式,如果CPU性能不强或者CPU核数不多,再或者磁盘性能较弱,编译就会很慢。使用笔记本来开发ROM就很麻烦,可能需要经常地去删一些build目录,而且性能不够用。而每个人给配一个工作站,多挂几个硬盘,使用的成本就很高,公司就不答应了。

所以我们最早是直接申请一个空间很大的云主机或者云物理机,直接在云主机上搭建ROM开发环境的。燃鹅事情的发展不会总是那么顺利,我们发现,云主机的空间也会不够用,公司的云主机环境会变动,这就导致我们经常需要迁移环境,造成的后果就是,辛苦安装的从Android4.4到Android8.0的编译环境以及一些配套的工具都需要重装一遍。更悲伤的是,我们之前的环境一直是基于Ubuntu14的,迁移之后,公司只提供Ubuntu16的镜像。导致像Android4.4这样低版本的系统的编译会出问题,一些工具也在Ubuntu16上也缺失了。

如果没有遇到这些问题,我们不会想到一个更好的策略——把环境装在Docker容器里面。然后我们把这个容器打包成镜像,维护这个镜像就好了。

而对于远程开发,有些开发Framework的同学可能不会适应,使用VIM来开发,远程替换资源这样的工作繁琐、重复而痛苦。所以我在2018年初的时候就在寻找一款远程开发工具,它就是Visual Studio Code。我们大概是最早使用VS Code的远程开发功能的ROM团队。

废话这么多,也就是为了说两个神器:

以下就是环境搭建的具体过程了,如果你有更好的办法或者建议,欢迎给我留言、评论。

环境准备

1、修改软件源

提高软件包安装速度,以及防止一些工具安装不上。

$ mv /etc/apt/sources.list /etc/apt/sources.list.bak
$ sudo vim /etc/apt/sources.list
# USTC (University of Science and Technology of Thina)
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse

deb https://packages.grafana.com/oss/deb stable main
# deb-src https://packages.grafana.com/oss/deb stable main

2、Docker 安装、配置

docker安装:

wget -qO- https://get.docker.com/ | sh
sudo service docker start
# 以非root用户运行
sudo usermod -aG docker rom

镜像加速:

$ vim /etc/docker/daemon.json
{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}

修改容器、镜像存储位置:

$ sudo vim /etc/systemd/system/multi-user.target.wants/docker.service
# 修改如下一行,--graph指定目录
ExecStart=/usr/bin/dockerd --graph=/opt/docker -H fd:// --containerd=/run/containerd/containerd.sock

$ sudo service docker restart
$ docker info

基于镜像创建容器:

# 安装lamp镜像
$docker pull linode/lamp
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
linode/lamp         latest              2359fa12fded        4 years ago         372MB
# 把lamp镜像重新命名为romer
docker tag 2359fa12fded romer
# 创建容器并指定容器名为romer
mkdir /opt/www
touch /opt/www/apache2.conf
touch /opt/www/my.cnf
docker run --name romer -p 80:80 -p 3306:3306 -it linode/lamp /bin/bash

linode/lamp镜像说明

www.linode.com/docs/applic…

linode/lamp是一个基于Ubuntu14的镜像,如果不能满足需要可以到Docker的镜像仓库寻找其它镜像。

ROM 编译环境安装

上面最后执行的命名会创建一个linode/lamp镜像对应的容器,并登录到那个Docker容器。你可以执行下面的命令查看的这个容器并登录上去。

# 查看所有容器
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                     PORTS               NAMES
a166e056b85b        linode/lamp         "/bin/bash"         About a minute ago   Exited (0) 5 seconds ago                       roman
# 启动容器
docker start a166e056b85b
# 进入容器
docker exec -it a166e056b85b /bin/bash 

安装ROM编译环境

Android各个版本依赖的Linux工具比较多,这里我写了一个脚本来执行安装,可能有几个工具是缺少的,需要在实际编译ROM时再补充给安装上。

#!/bin/bash
failed_infos=()
log_error() {
    failed_infos[${#failed_infos[@]}]=$1
    echo $2
}

# install tools for rom building
build_utils="libstdc++6 git flex bison gperf build-essential libx11-dev:i386 \
    libreadline6-dev:i386 libgl1-mesa-dev tofrodos python-markdown g++-multilib \
    libxml2-utils xsltproc dpkg-dev libsdl1.2-dev libesd0-dev git-core gnupg flex \
    bison gperf build-essential zip curl zlib1g-dev gcc-multilib libc6-dev-i386 \
    lib32z-dev lib32ncurses5-dev x11proto-core-dev libx11-dev libgl1-mesa-dev \
    libxml2-utils xsltproc unzip m4 bc lzop libesd0-dev squashfs-tools build-essential \
    zip curl libncurses5-dev pngcrush schedtool libxml2 libxml2-utils \
    gcc-multilib libswitch-perl libssl1.0.0 libssl-dev git gnupg flex bison gperf \
    build-essential zip curl libc6-dev x11proto-core-dev \
    libgl1-mesa-dev g++-multilib tofrodos python-markdown libxml2-utils xsltproc \
    mingw32 lib32readline-gplv2-dev libwxgtk2.8-dev zlib1g-dev:i386"

IFS=" "
build_utils_arr=($build_utils)

for util in "${build_utils_arr[@]}"
do
    echo "install $util >>>"
    sudo apt-get install -y $util || log_error $util "install $util failed!"
done

echo "${#failed_infos[*]} utils install failed. "
echo ${failed_infos[*]}

此外还有一些Java的环境,还请自行安装。(JDK6、JDK7、JDK8、OpenJDK7、OpenJDK8z这些都是会使用到的)

打包容器

保存修改:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS                                        NAMES
ef6648391c18        linode/lamp         "/bin/bash"         22 hours ago        Up 4 minutes             0.0.0.0:80->80/tcp, 0.0.0.0:3306->3306/tcp   romer
# 创建romer镜像,tag是v1
$ docker commit -a "xxx" -m "install build utils" ef6648391c18 romer:v1
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
romer               v1                  52055c310a81        2 minutes ago       2.26GB
linode/lamp         latest              2359fa12fded        4 years ago         372MB

# 生成新的容器。名为romerv2
# docker run --name romerv2 -p 80:80 -p 3306:3306 -v /opt/roman:/android/Release -v /opt/workspace:/workspace -it romer:v1 /bin/bash
docker run --name romerv1.1 -p 80:80 -p 3306:3306 -p 8080:8080 -p 4000:4000 -v /opt/roman:/android/Release -it romer:v1.1 /bin/bash

安装好你所需要的一系列工具之后,最好把容器打包下来,以方便备份和恢复。

# docker export :将容器文件系统作为一个tar归档文件导出到STDOUT
# -o :将输入内容写到文件。
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS                                        NAMES
d047c7ac6534        phusion/baseimage   "/bin/bash"         2 minutes ago       Exited (0) About a minute ago                                                test
ef6648391c18        linode/lamp         "/bin/bash"         21 hours ago        Up 21 hours                     0.0.0.0:80->80/tcp, 0.0.0.0:3306->3306/tcp   roman
$ docker export -o romer.tar ef6648391c18

# docker import : 从归档文件中创建镜像。
# docker import romer.tar my_romer:v1 

此外,我们还安装了一些和我们的定制ROM配套使用的工具(比如Jenkins、Tomcat)和自研软件/脚本。最后得到了一个大小为4GB的镜像,可以说很好迁移了。由于我们的镜像涉及到一些业务的东西,不方便分享出来。

ROM编译

我们的ROM的编译,是由一整套编译脚本来管理的,涉及到了以下流程:

不知道和大家的流程是怎么样的?希望能和大家一起分享、交流!

VSCode 远程开发

这一部分的内容可以暂时先参考我的VS Code 远程插件使用教程,或者别的同学的VS Code远程开发教程。

由于我们之前都是直接在云主机上进行远程开发的,现在需要搬到Docker容器中进行远程开发。理论上,通过端口映射的方式,是可以直接通过ssh登录到Docker容器的,小伙伴们可以尝试一下。这里等我把问题解决了,再来分享给大家。

附录

Docker常用命令:

# 查看所有容器
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                     PORTS               NAMES
a166e056b85b        linode/lamp         "/bin/bash"         About a minute ago   Exited (0) 5 seconds ago                       roman
# 删除容器
$ docker rm a166e056b85b
# 启动容器
docker start a166e056b85b
# 停止容器
docker stop a166e056b85b
# 进入容器
docker exec -it a166e056b85b /bin/bash  

# 查看镜像
docker images
# 删除镜像
$ docker rmi $imageId

# 和宿主机互传文件
docker cp 30026605dcfe:/home/cloudera/RS-MapReduce /tmp/

# 容器重命名
docker rename 原容器名  新容器名