daisy_workflows/linux_common/utils/diskutils.py (51 lines of code) (raw):

#!/usr/bin/env python3 # Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Disk utility functions for all VM scripts.""" import logging import utils from .common import AptGetInstall try: import guestfs except ImportError: AptGetInstall(['python3-guestfs']) import guestfs _STATUS_PREFIX = 'TranslateStatus: ' def log_key_value(key, value): """ Prints the key and value using the format defined by Daisy's serial output inspector. The format is defined in `daisy/step_wait_for_instances_signal.go` """ print(_STATUS_PREFIX + "<serial-output key:'%s' value:'%s'>" % (key, value)) def get_physical_drives(): rc, output = utils.Execute(['lsblk', '--noheadings', '--output=NAME', '--paths', '--list', '--nodeps', '-e7'], capture_output=True) disks = [] if rc == 0: disks = output.split('\n') disks.remove('') else: logging.info('Warning: Failed to excute \'lsblk\' cmd, ' 'Continuing anyway assuming that there are only two disks.') disks = ['/dev/sda', '/dev/sdb'] return disks def MountDisks(disks) -> guestfs.GuestFS: # All new Python code should pass python_return_dict=True # to the constructor. It indicates that your program wants # to receive Python dicts for methods in the API that return # hashtables. g = guestfs.GuestFS(python_return_dict=True) # Set the product name as cloud-init checks it to confirm this is a VM in GCE g.config('-smbios', 'type=1,product=Google Compute Engine,manufacturer=Google') g.set_memsize(4096) # Enable network g.set_network(True) # Attach the disk image to libguestfs. for disk in disks: g.add_drive_opts(disk) # Run the libguestfs back-end. g.launch() # Ask libguestfs to inspect for operating systems. roots = g.inspect_os() if len(roots) == 0: raise Exception('inspect_vm: no operating systems found') # Sort keys by length, shortest first, so that we end up # mounting the filesystems in the correct order. mps = g.inspect_get_mountpoints(roots[0]) g.gcp_image_distro = g.inspect_get_distro(roots[0]) g.gcp_image_major = str(g.inspect_get_major_version(roots[0])) g.gcp_image_minor = str(g.inspect_get_minor_version(roots[0])) for device in sorted(list(mps.keys()), key=len): try: g.mount(mps[device], device) except RuntimeError as msg: logging.warn('%s (ignored)' % msg) return g def UnmountDisk(g): try: g.umount_all() except Exception as e: logging.debug(str(e)) logging.warn('Unmount failed. Continuing anyway.')