2828## functions
2929##
3030
31+ # util wrapper around subprocess
32+ def _exec (cmd , * args , stdout = subprocess .PIPE , stderr = subprocess .PIPE , encoding = 'utf-8' , shlexsplit = False , ** kwargs ):
33+ '''
34+ wrapper around subprocess to default common arguments while allowing overriding.
35+ '''
36+ if shlexsplit :
37+ cmd = shlex .split (cmd )
38+ return subprocess .run (cmd , ** kwargs , stdout = stdout , stderr = stderr , encoding = encoding )
39+
40+
41+ # util to try to guess the truthiness of a string
42+ def str2bool (s ):
43+ """Converts an on/off, yes/no, true/false string to
44+ True/False."""
45+ if type (s ) == bool :
46+ return s
47+ if s and s .upper () in [ 'ON' , 'YES' , 'Y' , 'TRUE' , '1' ]:
48+ return True
49+ else :
50+ return False
51+
52+
3153def nukeLVM (volumegroup ):
3254 for (display , remove ) in [
3355 ('lvdisplay --all -c' , 'lvremove --force' ),
@@ -48,6 +70,7 @@ def nukeLVM(volumegroup):
4870 stdout = FNULL ,
4971 stderr = subprocess .STDOUT )
5072
73+
5174def stopMD ():
5275 #
5376 # we need to stop all MDs before we can remove them
@@ -63,34 +86,51 @@ def nukeMD(part):
6386 stderr = subprocess .STDOUT )
6487
6588
66- def nukeDisk (disk ):
67- if 'disklabel' in attributes :
68- disklabel = attributes ['disklabel' ]
69- else :
70- disklabel = 'gpt'
89+ def nukeDisk (disk , disklabel , halt_on_error ):
90+ '''
91+ destroy the master boot record (via dd),
92+ create a new partition label (msdos/gpt) based on the 'disklabel' attribute
93+ attempts to unmount any partitions on that disk that may be mounted
94+ '''
95+
96+ # unmount everything on the disk first.
97+ # NOTE: sles11 does not have the version of umount that allows recursive `umount -A /dev/some/`
98+ # so instead, iterate over partitions per disk, umounting parts only if mounted.
99+
100+ subproc_args = {'stdout' : subprocess .PIPE , 'stderr' : subprocess .STDOUT , 'check' : halt_on_error }
101+
102+ cmd = f'lsblk --raw --noheadings -o name,mountpoint /dev/{ disk } '
103+ proc = _exec (cmd , shlexsplit = True , ** subproc_args )
104+
105+ cmd = 'umount -f /dev/{}'
106+ for line in proc .stdout .splitlines ():
107+ line = line .split ()
108+
109+ if len (line ) == 2 :
110+ _exec (cmd .format (f'{ line [0 ]} ' ), shlexsplit = True , ** subproc_args )
71111
72- #
73112 # Clear out the master boot record of the drive
74- #
75113 cmd = 'dd if=/dev/zero of=/dev/%s count=512 bs=1' % disk
76- subprocess .call (shlex .split (cmd ),
77- stdout = FNULL , stderr = subprocess .STDOUT )
114+ _exec (cmd , shlexsplit = True , ** subproc_args )
78115
116+ # install new partition table
79117 cmd = 'parted -s /dev/%s mklabel %s' % (disk , disklabel )
80- subprocess .call (shlex .split (cmd ),
81- stdout = FNULL , stderr = subprocess .STDOUT )
82-
83- return
118+ _exec (cmd , shlexsplit = True , ** subproc_args )
84119
85120##
86121## MAIN
87122##
88123
124+ # get info about attributes
125+
89126if 'nukecontroller' in attributes :
90127 nukecontroller = attributes ['nukecontroller' ]
91128else :
92129 nukecontroller = 'false'
93130
131+ halt_on_error = str2bool (attributes .get ('halt_install_on_error' , True ))
132+ disklabel = attributes .get ('disklabel' , 'gpt' )
133+
94134if 'nukedisks' in attributes :
95135 n = attributes ['nukedisks' ]
96136
@@ -199,5 +239,9 @@ def nukeDisk(disk):
199239#
200240for disk in disks :
201241 if disk ['nuke' ]:
202- nukeDisk (disk ['device' ])
203-
242+ try :
243+ nukeDisk (disk ['device' ], disklabel , halt_on_error )
244+ except subprocess .CalledProcessError as e :
245+ print (' ' .join (e .cmd ))
246+ print (f'output: { e .stdout } ' )
247+ sys .exit (1 )
0 commit comments