真实用例

实例 1

# 在与当前脚本同级的目录下有 com.tophant.prs.nta-light-api.ambotup 文件

resources_dir = '/data/.ambot/4.8-upgrade/code-upgrade/'
exec('mkdir -p ' + resources_dir, on='+nta-light-api')
upload("com.tophant.prs.nta-light-api.ambotup", "+nta-light-api:" + resources_dir)
exec("chmod +x " + resources_dir + "/com.tophant.prs.nta-light-api.ambotup", on="+nta-light-api")
exec(resources_dir + "/com.tophant.prs.nta-light-api.ambotup -y --author 'Jenkins <ci@tophant.com>' --unsafe-allow-dirty --start nta-light-api", on="+nta-light-api")

这个脚本做了以下几件事情

  • 声明 resources_dir 变量,为存储的资源路径
  • 在存在「nta-light-api」服务的机器上创建了这个资源路径
  • 将 up 升级包传到了存在「nta-light-api」服务的机器上的资源路径下
  • 给这个升级包赋予了可执行权限
  • 执行这个升级包

在这个例子中,ambot-script 提供了以下能力

  • 上传文件到符合条件的机器上
  • 在符合条件的机器上执行命令

建议改写

resources_dir = '/data/.ambot/4.8-upgrade/code-upgrade/'
pkg_id = 'com.tophant.prs.nta-light-api'
services = ['nta-light-api']

# ---------- #

assert(core.is_master())

target = ":" + pkg_id
pkg_file = pkg_id + ".ambotup"
pkg_upload_to = os.path.join(resources_dir, pkg_file)

exec(['mkdir', '-p', resources_dir], on=target)
upload(pkg_file, "{}:{}".format(target, resources_dir))
exec(['chmod', '+x', pkg_upload_to], on=target)
exec([pkg_upload_to, '-y', '--author', 'Jenkins <ci@tophant.com>', '--start', ','.join(services)], on=target)
  1. 在升级类脚本的第一行加上 assert(core.is_master()) 是一个好习惯
  2. exec 执行的命令在不使用 bash 高级功能时优先使用 list 传递而非拼接字符串
  3. 路径的拼接有问题(resources_dir 已经以 / 结尾了)
  4. 自动化脚本中禁止使用任何 --unsafe 的功能
  5. 将公有参数提出来作为变量,方便脚本复用

进一步的优化空间?

(下一场培训)

实例 2

allServers=core.resolve('all')
centos8Servers=core.resolve('.sensor')
centos7Servers = []

for s in allServers:
    if s not in centos8Servers:
        centos7Servers.append(s)

run("mkdir -p /data/update-polkit/", on="all")

upload("polkit-el7", "(%s):/data/update-polkit/" % ",".join(centos7Servers))
upload("polkit-el8", "(%s):/data/update-polkit/" % ",".join(centos8Servers))

run("rpm -Uvh /data/update-polkit/polkit-el7/*.rpm", on=centos7Servers)
run("rpm -Uvh /data/update-polkit/polkit-el8/*.rpm", on=centos8Servers)

ret = run("ambot-run -- rpm -qa polkit")

print("")
print("========== after update", color=GREEN)
print(ret.stdout)

这个脚本用到了:

  1. core.resolve
  2. upload 支持传递多个目标机器

这个脚本的问题

  1. run 命令需要手动判断返回值,请换成 exec
  2. upload 命令和 run 命令所传递的目标参数有可能为空
  3. 不要套娃 ambot-run

改写

allServers = core.resolve('all')
centos8Servers = core.resolve('.sensor')
centos7Servers = [x for x in allServers if x not in centos8Servers]

assert(run("mkdir -p /data/update-polkit/", on="all"))

if centos8Servers:
	upload("polkit-el8", "(%s):/data/update-polkit/" % ",".join(centos8Servers))
	assert(run("rpm -Uvh /data/update-polkit/polkit-el8/*.rpm", on=centos8Servers))

if centos7Servers:
	upload("polkit-el7", "(%s):/data/update-polkit/" % ",".join(centos7Servers))
	assert(run("rpm -Uvh /data/update-polkit/polkit-el7/*.rpm", on=centos7Servers))


print()
print("========== after update", color=GREEN)

exec("rpm -qa polkit", on='all')