github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/boot/localboot/localboot.go (about) 1 // Copyright 2020 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package localboot contains helper functions for booting off local disks. 6 package localboot 7 8 import ( 9 "context" 10 "fmt" 11 "io/ioutil" 12 "os" 13 "path/filepath" 14 15 "github.com/u-root/u-root/pkg/boot" 16 "github.com/u-root/u-root/pkg/boot/bls" 17 "github.com/u-root/u-root/pkg/boot/esxi" 18 "github.com/u-root/u-root/pkg/boot/grub" 19 "github.com/u-root/u-root/pkg/boot/syslinux" 20 "github.com/u-root/u-root/pkg/mount" 21 "github.com/u-root/u-root/pkg/mount/block" 22 "github.com/u-root/u-root/pkg/ulog" 23 ) 24 25 // parse treats device as a block device with a file system. 26 func parse(l ulog.Logger, device *block.BlockDev, mountDir string) []boot.OSImage { 27 imgs, err := bls.ScanBLSEntries(l, mountDir) 28 if err != nil { 29 l.Printf("No systemd-boot BootLoaderSpec configs found on %s, trying another format...: %v", device, err) 30 } 31 32 grubImgs, err := grub.ParseLocalConfig(context.Background(), mountDir) 33 if err != nil { 34 l.Printf("No GRUB configs found on %s, trying another format...: %v", device, err) 35 } 36 imgs = append(imgs, grubImgs...) 37 38 syslinuxImgs, err := syslinux.ParseLocalConfig(context.Background(), mountDir) 39 if err != nil { 40 l.Printf("No syslinux configs found on %s: %v", device, err) 41 } 42 imgs = append(imgs, syslinuxImgs...) 43 44 return imgs 45 } 46 47 // parseUnmounted treats device as unmounted, with or without partitions. 48 func parseUnmounted(l ulog.Logger, device *block.BlockDev) ([]boot.OSImage, []*mount.MountPoint) { 49 // This will try to mount device partition 5 and 6. 50 imgs, mps, err := esxi.LoadDisk(device.DevicePath()) 51 if err != nil { 52 l.Printf("No ESXi disk configs found on %s: %v", device, err) 53 } 54 55 // This tries to mount the device itself, in case it's an installer CD. 56 img, mp, err := esxi.LoadCDROM(device.DevicePath()) 57 if err != nil { 58 l.Printf("No ESXi CDROM configs found on %s: %v", device, err) 59 } 60 if img != nil { 61 imgs = append(imgs, img) 62 mps = append(mps, mp) 63 } 64 // Convert from *MultibootImage to OSImage. 65 var images []boot.OSImage 66 for _, i := range imgs { 67 images = append(images, i) 68 } 69 return images, mps 70 } 71 72 // Localboot tries to boot from any local filesystem by parsing grub configuration 73 func Localboot(l ulog.Logger, blockDevs block.BlockDevices) ([]boot.OSImage, []*mount.MountPoint, error) { 74 mountPoints, err := ioutil.TempDir("", "u-root-boot") 75 if err != nil { 76 return nil, nil, fmt.Errorf("cannot create tmpdir: %v", err) 77 } 78 79 var images []boot.OSImage 80 var mps []*mount.MountPoint 81 for _, device := range blockDevs { 82 imgs, mmps := parseUnmounted(l, device) 83 if len(imgs) > 0 { 84 images = append(images, imgs...) 85 mps = append(mps, mmps...) 86 } else { 87 dir := filepath.Join(mountPoints, device.Name) 88 89 os.MkdirAll(dir, 0777) 90 mp, err := device.Mount(dir, mount.ReadOnly) 91 if err != nil { 92 os.RemoveAll(dir) 93 continue 94 } 95 96 imgs = parse(l, device, dir) 97 images = append(images, imgs...) 98 mps = append(mps, mp) 99 } 100 } 101 return images, mps, nil 102 }