腾讯云自定义镜像为何不支持购买cvm时将一并加购的数据盘初始化

2023-08-31 17:52:31 浏览数 (1)

需求:想要购买cvm时初始化数据盘

解决方案:购买cvm的时候,选公共镜像,在cvm购买界面上一并加购数据盘并勾选初始化复选框,然后就会自动化分好区;自定义镜像不行,平台的考虑是:自定义镜像千差万别,平台无法确认客户自定义镜像的init环境,因此前端才没设计那个勾选按钮,不过初始化数据盘本质上是通过init的userdata起作用的,理论上在userdata里传入选公共镜像时勾选初始化数据盘后userdata部分的代码的话,自定义镜像也可以实现初始化数据盘,前提是自定义镜像的init是ok的(linux对应cloudinit,windows对应cloudbase-init)

优化后的windows数据盘初始化代码如下

原本代码里没有匹配上大小是TB的情况,所以大盘不会被初始化,然后我加了匹配大盘的逻辑,把日志输出弄细了些方便出现异常的时候可以回溯定位问题,并增加了≥16TB盘的逻辑:超过16T的盘应该按8192的块大小分区,默认块大小4096最大只能支持到16T分区,超过16TB的那部分空白空间用不上

目前在2008R2、2012R2、2016、2019、2022中文版测试挂20块32000GB的盘进行极限测试是可以顺利初始化的

代码语言:javascript复制
#ps1

$Global:UserMount = 'E'
$Global:TotalDataDisk = 0
$disks =Get-WmiObject Win32_DiskDrive |   Where {$_.Partitions -eq 0} | select DeviceID,Size|findstr /i PHYSICALDRIVE | ForEach-Object { ($_.split("E ")[1].PadLeft(2))   ','   ($_.Split(" ")[-1]) }|sort

function SetAllDiskOnline {
    Write-Output 'SetAllDiskOnline' >> C:disk_init.txt
    $DiskList = 'list disk' | diskpart.exe
    Write-Output $DiskList >> C:disk_init.txt
    foreach ($Disk in $DiskList) {
        if ($Disk -match 'Disks (?<DiskIdx>d ) | u78c1u76d8s (?<DiskIdx>d )') {
            $DiskIdx = $Matches.DiskIdx
            Write-Output "Setting disk $DiskIdx online" >> C:disk_init.txt
            if ([int]$DiskIdx -ge 1) {
                $Global:TotalDataDisk = $Global:TotalDataDisk   1
                $DiskOps = @"
select disk $DiskIdx
online disk
san policy=OnlineAll
exit
"@
                $DiskOps | diskpart.exe | Out-Null
                Start-Sleep -Seconds 0.1
            }
        }
    }
}

function CheckShouldInit {
    Write-Output 'CheckShouldInit' >> C:disk_init.txt
    $VolumeList = 'list volume' | diskpart.exe
    $TotalVolume = 0
    foreach ($Volume in $VolumeList) {
        if ($Volume -match 'Volumes (?<VolumeIdx>d ) | u5377s (?<VolumeIdx>d )') {
            $TotalVolume = $TotalVolume   1
        }
    }
    if ($TotalVolume -gt 3) {
        Write-Output 'Not a new instance, exit' >> C:disk_init.txt
        exit
    }
    Write-Output 'New instance to be initilized' >> C:disk_init.txt
}

function InitDataDisk {
    Write-Output 'InitDataDisk' >> C:disk_init.txt
    $DiskList = 'list disk' | diskpart.exe
    $DriverLetterList = [char[]](69..90)
    $Idx = 0
    foreach ($Disk in $DiskList) {
        if ($Disk -match 'Disks (?<DiskIdx>d )s (Online|Offline)s (?<Size>d )s GBs (?<Free>d )|u78c1u76d8s (?<DiskIdx>d )s (u8054u673a|u8131u673a)s (?<Size>d )s GBs (?<Free>d )|Disks (?<DiskIdx>d )s (Online|Offline)s (?<Size>d )s TBs (?<Free>d )|u78c1u76d8s (?<DiskIdx>d )s (u8054u673a|u8131u673a)s (?<Size>d )s TBs (?<Free>d )') {
            $DiskIdx = $Matches.DiskIdx
            if ($DiskIdx -ge 1) {
                $DriverLetter = $DriverLetterList[$Idx]
                if ($Global:TotalDataDisk -le 1) {
                    $DriverLetter = $Global:UserMount
                }




				$disktype="mbr"
				if(([Math]::Round($disks[$DiskIdx-1].split(",")[1]/1024/1024/1024)) -gt 2048)
				{
				$disktype="gpt"
				}

				$unit=4096
				if(([Math]::Round($disks[$DiskIdx-1].split(",")[1]/1024/1024/1024)) -gt 16384)
				{
				$unit=8192
				}

                $DiskOps = @"
SELECT DISK $DiskIdx
online disk NOERR
attr disk clear readonly NOERR
convert $disktype NOERR
CREATE PARTITION PRIMARY NOERR
format fs=ntfs unit=$unit quick NOERR
ASSIGN LETTER=$DriverLetter
san policy=onlineall
EXIT
"@

                Write-Output "Start initializing disk $DiskIdx" >> C:disk_init.txt
                $DiskOps | diskpart.exe >> C:disk_init.txt

                Start-Sleep -Seconds 0.1

                Write-Output "DataDisk $DiskIdx is assigned to driver: $DriverLetter" >> C:disk_init.txt
                $Idx = $Idx   1
            }
        }
    }
}

Write-Output 'Initializing data disks' >> C:disk_init.txt

SetAllDiskOnline

CheckShouldInit
InitDataDisk

0 人点赞