|
|||||||
Скрипт для уменьшения размеров VDI-файлов в каталоге и подкаталогах
Время создания: 24.11.2022 15:07
Автор: xintrea
Текстовые метки: linux, VirtualBox, python, python3, скрипт, VDI, диск, размер, уменьшение, очистка
Раздел: Компьютер - Linux - Виртуализация и эмуляция - VirtualBox
Запись: xintrea/mytetra_syncro/master/base/1669291630i55g2cazwr/text.html на raw.github.com
|
|||||||
|
|||||||
Ниже приведен скрипт, который уменьшает размеры VDI-файлов дисков виртуальной машины VirtuslBox. Предполагается, что VDI-файлы имеют динамически изменяемый формат хранения. Скрипт рекурсивно ищет все VDI-файлы в указанном каталоге и всех подкаталогах, и обрабатывает их. В среднем объем файлов образов дисков уменьшается на 30-60% для виртуальных машин, которые проработали некоторое время и в них устанавливались и удалялись какие-то пакеты, шла работа с переносом/копированием/удалением файлов, работала база данных. Для работы скрипта в хостовой системе должна быть установлена утилита zerofree. Каталог /media/vdi должен быть заранее создан и доступен для записи. Скрипт вызывается с правами root, так как используются команды монтирования и создания символьных устройств. Данный скрипт может пригодиться для массовой обработки виртуальных машин на сервере виртуализации. В момент выполнения скрипта виртуальные машины, диски которых обрабатываются, должны быть потушены, чтобы данные не были испорчены. Никаких проверок на то, что образ диска в данный момент занят в виртуальной машине, не предусмотрено. Использование скрипта: clearVdi.py <обрабатываемая_директория> Код скрипта следующий: #!/usr/bin/python3 # Данный скрипт принимает каталог, в котором он будет искать VDI-файлы. # Поиск будет происходить также и в подкаталогах # Каждый найденный файл образа будет обрабатываться через zerofree # А так же данный файл будет уменьшаться через механизмы VirtualBox import os import sys import re import time from subprocess import Popen, PIPE def main(): if len(sys.argv)!=2 : print("Не указан обрабатываемый каталог") exit(1) startDir=sys.argv[1] if not os.path.isdir(startDir) : print("Не найден каталог "+startDir) exit(1) if not os.path.isdir("/media/vdi") : print("Не найден каталог для монтирования диска виртуальной машины /media/vdi") exit(1) vdiFiles = [os.path.join(dp, f) for dp, dn, filenames in os.walk(startDir) for f in filenames if os.path.splitext(f)[1] == '.vdi'] print("Будут обработаны файлы:") print(vdiFiles) keepBytes=0 for fileName in vdiFiles: print("\nФайл "+fileName) runSmart("Создание символьного устройства", "qemu-nbd -c /dev/nbd0 '"+fileName+"'") runSmart("Монтирование диска "+fileName, "mount -o noatime,noexec,ro /dev/nbd0p1 /media/vdi") sizeBefore=os.path.getsize(fileName) print("Размер файла до обработки: "+'{0:,}'.format( sizeBefore ).replace(',', ' ') ) runSmart("Запуск zerofree", "zerofree -v /dev/nbd0p1") runSmart("Размонтирование диска "+fileName, "umount /dev/nbd0p1") runSmart("Отключение символьного устройства", "qemu-nbd -d /dev/nbd0") runSmart("Уменьшение размера "+fileName, "vboxmanage modifymedium --compact '"+fileName+"'") sizeAfter=os.path.getsize(fileName) print("Размер файла после обработки: "+'{0:,}'.format( sizeAfter ).replace(',', ' ') ) print("Размер уменьшен на "+str(int(100-sizeAfter*100/sizeBefore))+"%") keepBytes=keepBytes+(sizeBefore-sizeAfter) print("Освобождено "+'{0:,}'.format( keepBytes ).replace(',', ' ')+" байт") # Запуск команды с проверкой результата def runSmart(title, command) : print(title) result=run(command) time.sleep(1) if result[2]!=0 : print("Невозможно выполнить действие: "+title) print(command) print(result[0]+"\n"+result[1]) exit(1) # Запуск внешней программы def run(cmd) : p=Popen(cmd, stdout=PIPE, shell=True) stdOutData, stdErrData = p.communicate() errCode=p.returncode outData="" errData="" if not stdOutData is None : outData=stdOutData.decode() if not stdErrData is None : errData=stdErrData.decode() # Убирается последний перенос строк, чтобы в конце небыло пустой строки outData=re.sub("\n$", '', outData ) errData=re.sub("\n$", '', errData ) return(outData, errData, errCode) # Конструкция чтобы работала функция main() if __name__ == '__main__': main() Пример работы скрипта: Будут обработаны файлы: ['/opt/astra16up10_domain/Astra16up10DomainClient/Astra16up10DomainClient.vdi', '/opt/astra16up10_domain/Astra16up10DomainClientMt2/Astra16up10DomainClientMt2.vdi', '/opt/astra16up10_domain/Astra16up10DomainHost/Astra16up10DomainHost.vdi'] Файл /opt/astra16up10_domain/Astra16up10DomainClient/Astra16up10DomainClient.vdi Создание символьного устройства Монтирование диска /opt/astra16up10_domain/Astra16up10DomainClient/Astra16up10DomainClient.vdi Размер файла до обработки: 10 874 781 696 Запуск zerofree 100.0% Размонтирование диска /opt/astra16up10_domain/Astra16up10DomainClient/Astra16up10DomainClient.vdi Отключение символьного устройства Уменьшение размера /opt/astra16up10_domain/Astra16up10DomainClient/Astra16up10DomainClient.vdi 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100% Размер файла после обработки: 8 348 762 112 Размер уменьшен на 23% Файл /opt/astra16up10_domain/Astra16up10DomainClientMt2/Astra16up10DomainClientMt2.vdi Создание символьного устройства Монтирование диска /opt/astra16up10_domain/Astra16up10DomainClientMt2/Astra16up10DomainClientMt2.vdi Размер файла до обработки: 10 878 976 000 Запуск zerofree 100.0% Размонтирование диска /opt/astra16up10_domain/Astra16up10DomainClientMt2/Astra16up10DomainClientMt2.vdi Отключение символьного устройства Уменьшение размера /opt/astra16up10_domain/Astra16up10DomainClientMt2/Astra16up10DomainClientMt2.vdi 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100% Размер файла после обработки: 8 370 782 208 Размер уменьшен на 23% Файл /opt/astra16up10_domain/Astra16up10DomainHost/Astra16up10DomainHost.vdi Создание символьного устройства Монтирование диска /opt/astra16up10_domain/Astra16up10DomainHost/Astra16up10DomainHost.vdi Размер файла до обработки: 14 773 387 264 Запуск zerofree 100.0% Размонтирование диска /opt/astra16up10_domain/Astra16up10DomainHost/Astra16up10DomainHost.vdi Отключение символьного устройства Уменьшение размера /opt/astra16up10_domain/Astra16up10DomainHost/Astra16up10DomainHost.vdi 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100% Размер файла после обработки: 8 585 740 288 Размер уменьшен на 41% Освобождено 11 221 860 352 байт |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|