Jenkins动态绑定节点设备ID:多物理机USB设备适配方案

Jenkins动态绑定节点设备ID:多物理机USB设备适配方案

一、需求背景

在多物理机节点的Jenkins环境中,不同节点(物理机)会绑定不同的USB设备(如Android手机、NG手表、iOS设备),需实现:

  1. 流水线根据测试需求(如"仅测Android""测Android+NG"),自动筛选绑定对应设备的节点;
  2. 无需手动输入设备ID,流水线自动读取当前节点预配置的设备ID,实现"节点-设备"的动态绑定。

二、核心思路

通过节点标签+节点环境变量的组合实现:

  1. 节点标签:标记节点支持的设备类型(如"Android"表示节点绑定了Android设备,"Android && Ng"表示节点同时绑定Android+NG设备);
  2. 节点环境变量 :在节点中预配置设备对应的ID(如android_devices_id存Android设备ID,ng_devices_id存NG设备ID);
  3. 流水线通过"标签筛选节点",并读取该节点的环境变量,自动获取当前节点的设备ID。

三、步骤1:节点标签规划

为不同设备类型的节点定义统一标签规则(标签大小写敏感):

节点绑定的设备 节点标签(Label) 说明
仅Android手机 Android 流水线需测Android时,筛选该标签节点
Android手机 + NG手表 Android && Ng 流水线需同时测Android+NG时,筛选该标签节点
仅iOS设备 iOS 流水线需测iOS时,筛选该标签节点
仅NG手表 Ng 流水线需仅测NG时,筛选该标签节点

四、步骤2:节点环境变量配置(绑定设备ID)

在每个节点中配置对应设备的ID(以你的截图配置为例),步骤如下:

  1. 进入Jenkins管理 → 「管理Jenkins」→ 「节点」→ 选择目标节点(如你的物理机节点)→ 点击「配置」;

  2. 配置节点标签 :在「标签」输入框中填写步骤1规划的标签(如绑定Android+NG的节点填写master Android Ng);

  3. 配置设备ID环境变量

    • 勾选「节点属性」→ 「Environment variables」(环境变量);

    • 点击「添加」,按设备类型填写键-值对 (键名需全局统一,方便流水线读取):

      设备类型 环境变量键(Key) 环境变量值(Value) 说明
      Android手机 android_devices_id 你的Android设备ID(如8cb34c35 节点实际连接的Android设备ID
      NG手表 ng_devices_id 你的NG设备ID(如2511C0037676 节点实际连接的NG设备ID
      iOS设备 ios_devices_id 你的iOS设备ID 节点实际连接的iOS设备ID
  4. 点击「保存」,完成节点的设备ID与标签配置。

五、步骤3:流水线中动态筛选节点+获取设备ID

流水线通过标签筛选节点,并自动读取当前节点的环境变量,实现设备ID的动态获取。

核心代码逻辑

groovy 复制代码
pipeline {
    agent {
        // 步骤1:根据测试需求,筛选对应标签的节点
        // 示例:筛选同时绑定Android+NG的节点(标签为Android && Ng)
        label 'Android && Ng'
        
        // 若仅需Android节点,改为:label 'Android'
        // 若仅需iOS节点,改为:label 'iOS'
    }

    parameters {
        // 可选:参数化选择测试设备类型(自动匹配对应标签)
        choice(
            name: 'DEVICE_TYPE',
            choices: ['Android', 'Android+NG', 'iOS'],
            description: '选择测试设备类型'
        )
    }

    stages {
        stage('节点与设备ID校验') {
            steps {
                script {
                    // 步骤2:根据选择的设备类型,动态调整节点标签(可选,替代agent的固定label)
                    def targetLabel = ''
                    if (params.DEVICE_TYPE == 'Android') {
                        targetLabel = 'Android'
                    } else if (params.DEVICE_TYPE == 'Android+NG') {
                        targetLabel = 'Android && Ng'
                    } else if (params.DEVICE_TYPE == 'iOS') {
                        targetLabel = 'iOS'
                    }
                    // 重新绑定节点(若需参数化选择设备类型,需配合node块)
                    node(targetLabel) {
                        echo "当前选中节点:${env.NODE_NAME}"
                        echo "节点标签:${env.NODE_LABELS}"

                        // 步骤3:读取当前节点的设备ID(根据设备类型读取对应环境变量)
                        def deviceIds = [:]
                        if (params.DEVICE_TYPE.contains('Android')) {
                            deviceIds.android = env.android_devices_id
                            if (!deviceIds.android) {
                                error "当前节点未配置Android设备ID!"
                            }
                        }
                        if (params.DEVICE_TYPE.contains('NG')) {
                            deviceIds.ng = env.ng_devices_id
                            if (!deviceIds.ng) {
                                error "当前节点未配置NG设备ID!"
                            }
                        }
                        if (params.DEVICE_TYPE == 'iOS') {
                            deviceIds.ios = env.ios_devices_id
                            if (!deviceIds.ios) {
                                error "当前节点未配置iOS设备ID!"
                            }
                        }

                        // 输出设备ID(后续测试步骤可直接使用deviceIds中的值)
                        echo "当前节点绑定的设备ID:${deviceIds}"
                    }
                }
            }
        }

        stage('执行设备测试') {
            steps {
                script {
                    node(params.DEVICE_TYPE == 'Android' ? 'Android' : (params.DEVICE_TYPE == 'Android+NG' ? 'Android && Ng' : 'iOS')) {
                        // 实际测试步骤:直接使用节点的设备ID
                        def androidId = env.android_devices_id
                        def ngId = env.ng_devices_id
                        
                        echo "开始测试Android设备(ID:${androidId})"
                        // 执行Android测试命令(如adb连接、自动化脚本)
                        // bat "adb connect ${androidId}"

                        if (params.DEVICE_TYPE == 'Android+NG') {
                            echo "开始测试NG设备(ID:${ngId})"
                            // 执行NG设备测试命令
                        }
                    }
                }
            }
        }
    }
}

六、场景示例

示例1:仅测试Android设备的流水线

groovy 复制代码
pipeline {
    agent { label 'Android' } // 仅选绑定Android的节点
    stages {
        stage('测试Android设备') {
            steps {
                script {
                    def androidId = env.android_devices_id
                    echo "当前节点Android设备ID:${androidId}"
                    // 执行Android测试(如App自动化)
                    bat "adb devices | findstr ${androidId}" // 验证设备连接
                }
            }
        }
    }
}

示例2:测试Android+NG设备的流水线

groovy 复制代码
pipeline {
    agent { label 'Android && Ng' } // 选同时绑定Android+NG的节点
    stages {
        stage('测试Android+NG设备') {
            steps {
                script {
                    def androidId = env.android_devices_id
                    def ngId = env.ng_devices_id
                    echo "Android设备ID:${androidId} | NG设备ID:${ngId}"
                    // 执行跨设备联动测试(如Android与NG手表数据同步)
                }
            }
        }
    }
}

七、注意事项

  1. 标签大小写敏感 :节点标签(如Android)与流水线中label配置需完全一致(androidAndroid);
  2. 环境变量键名统一 :所有节点的同一类设备,需使用相同的环境变量键(如所有Android节点都用android_devices_id);
  3. 节点在线状态:确保筛选的标签对应的节点处于「在线」状态,否则流水线会卡住等待节点;
  4. 设备ID准确性 :环境变量中配置的设备ID需与节点实际连接的USB设备ID一致(可通过adb devices(Android)、专用工具(NG/iOS)验证);
  5. 标签逻辑运算
    • &&表示"且"(节点需同时具备多个标签);
    • 空格表示"或"(节点具备任一标签即可)。
相关推荐
乘云数字DATABUFF4 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
荣--6 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森6 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜7 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB8 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode9 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户03284722207010 天前
如何搭建本地yum源(上)
运维
大树8813 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠13 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质13 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务