You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过GCP Python SDK判断Compute Engine实例是Linux还是Windows

判断GCP Compute Engine实例的操作系统(Linux/Windows)

GCE实例本身的返回字段不直接包含操作系统类型,但可以通过以下两种可靠方式判断:

方案1:通过实例绑定的许可证快速判断

Windows实例会绑定微软专属的付费许可证,许可证URL中包含windows关键词;Linux实例一般使用开源许可证或无额外付费许可证,可直接通过检查实例的licenses字段判断,无需额外API调用。

方案2:通过引导磁盘关联的镜像信息判断

如果许可证无法判断(比如自定义镜像),可以从实例的引导磁盘追溯到关联的镜像,通过镜像名称、family或官方提供的os_distribution字段确定OS类型。


修改后的完整代码

import sys
import json

from google.oauth2 import service_account
from google.cloud import compute_v1


class VM:
    def __init__(self, cred_json_path):
        self.cred_json_path = cred_json_path
        self.credentials = self.create_credentials()
        self.page_size = 500

    def create_credentials(self):
        return service_account.Credentials.from_service_account_file(self.cred_json_path)

    def list_instance(self):
        compute_client = compute_v1.InstancesClient(credentials=self.credentials)
        disk_client = compute_v1.DisksClient(credentials=self.credentials)
        results = []
        project_id = self.credentials.project_id

        for _, instances in compute_client.aggregated_list(request={"project": project_id, "max_results": self.page_size}):
            if not instances.instances:
                continue
            for instance in instances.instances:
                os_type = "Unknown"

                # 优先通过许可证判断Windows
                if instance.licenses:
                    for license_url in instance.licenses:
                        if "windows" in license_url.lower():
                            os_type = "Windows"
                            break

                # 许可证未命中时,通过引导磁盘的镜像判断
                if os_type == "Unknown" and instance.disks:
                    boot_disk = instance.disks[0]
                    if boot_disk.source:
                        # 解析磁盘资源路径的各个部分
                        path_parts = boot_disk.source.split('/')
                        disk_name = path_parts[-1]
                        # 处理跨项目磁盘的情况
                        disk_project = path_parts[6] if len(path_parts) > 6 else project_id
                        disk_zone = path_parts[8] if len(path_parts) > 8 else instance.zone.split('/')[-1]

                        try:
                            # 获取磁盘详情,提取关联镜像
                            disk = disk_client.get(project=disk_project, zone=disk_zone, disk=disk_name)
                            if disk.source_image:
                                image_path_parts = disk.source_image.split('/')
                                image_name = image_path_parts[-1]
                                # 通过镜像名称关键词判断OS
                                if "windows" in image_name.lower():
                                    os_type = "Windows"
                                elif any(key in image_name.lower() for key in ["ubuntu", "debian", "centos", "rhel", "suse", "linux"]):
                                    os_type = "Linux"
                                # 可选:调用ImagesClient获取官方镜像的os_distribution字段
                                # image_client = compute_v1.ImagesClient(credentials=self.credentials)
                                # image = image_client.get(project=image_path_parts[6], image=image_name)
                                # os_type = image.os_distribution or "Unknown"
                        except Exception as e:
                            print(f"无法获取实例 {instance.name} 的磁盘信息: {str(e)}")

                # 给实例对象添加OS类型属性
                setattr(instance, 'os_type', os_type)
                results.append(instance)
        return results

    def show(self):
        instance_list = self.list_instance()
        for instance in instance_list:
            # 将proto对象转为字典并追加os_type
            instance_data = json.loads(json.dumps(instance))
            instance_data['os_type'] = instance.os_type
            print(json.dumps(instance_data, indent=2, ensure_ascii=False))


def main(cred_json_path):
    vm = VM(cred_json_path)
    vm.show()


if __name__ == '__main__':
    main(sys.argv[1])

注意事项

  1. 权限要求:需要为服务账号添加compute.disks.get权限(如果使用方案2),以及基础的compute.instances.list权限。
  2. 自定义镜像:如果使用自定义镜像,建议在创建镜像时添加包含OS类型的标签,或维护一份镜像名称与OS的映射表,避免关键词匹配失效。
  3. 性能优化:优先使用许可证判断,避免额外的API调用;如果需要批量处理大量实例,可以考虑批量获取磁盘/镜像信息,减少请求次数。

内容的提问来源于stack exchange,提问作者leo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 20:40:30