New workflow task: formatting a disk

70 views
Skip to first unread message

Nick McSpadden

unread,
May 14, 2015, 12:51:46 PM5/14/15
to imag...@googlegroups.com
I've been working on a fork that allows for formatting a volume or partitioning a disk as part of a deployment process.


Good news: it works!  You can test it and it should work!

There are two new types: "eraseVolume" and "partition".

The structure of config_imagr.plist looks like this:

Erasing a volume and using the default "Macintosh HD", Journaled HFS+:
<dict>
    <key>name</key>
    <string>Attempted Formatting</string>
    <key>description</key>
    <string>This will break everything you&apos;ve ever loved</string>
    <key>restart_action</key>
    <string>none</string>
    <key>bless_target</key>
    <false/>
    <key>components</key>
    <array>
        <dict>
            <key>type</key>
            <string>eraseVolume</string>
        </dict>
    </array>
</dict>

Erasing a volume with a new name:
<dict>
    <key>name</key>
    <string>Attempted Formatting</string>
    <key>description</key>
    <string>Erase & rename</string>
    <key>restart_action</key>
    <string>none</string>
    <key>bless_target</key>
    <false/>
    <key>components</key>
    <array>
        <dict>
            <key>type</key>
            <string>eraseVolume</string>
            <key>name</key>
            <string>My Partition</string>
        </dict>
    </array>
</dict>

Erasing with a new name and format type:
<dict>
    <key>name</key>
    <string>Attempted Formatting</string>
    <key>description</key>
    <string>Erase, rename, new format</string>
    <key>restart_action</key>
    <string>none</string>
    <key>bless_target</key>
    <false/>
    <key>components</key>
    <array>
        <dict>
            <key>type</key>
            <string>eraseVolume</string>
            <key>name</key>
            <string>My Partition</string>
            <key>format</key>
            <string>Journaled HFS+</string>
        </dict>
    </array>
</dict>

Partitioning a disk:
<dict>
    <key>name</key>
    <string>Attempted Formatting</string>
    <key>description</key>
    <string>Repartition</string>
    <key>restart_action</key>
    <string>none</string>
    <key>bless_target</key>
    <false/>
    <key>components</key>
    <array>
        <dict>
            <key>type</key>
            <string>partition</string>
            <key>map</key>
            <string>GPTFormat</string>
            <key>partitions</key>
            <array>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>Macintosh HD</string>
                    <key>size</key>
                    <string>50%</string>
                </dict>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>Data</string>
                    <key>size</key>
                    <string>50%</string>
                </dict>
            </array>
        </dict>
    </array>
</dict>

With partitioning, the defaults are "GPTFormat", one partition using 100% of the disk space, "Macintosh HD" using Journaled HFS+.  Any options not specified are defaulted.  No sanity checks are done if the admin does something like a 75% and 50% partition scheme, it'll just let diskutil try it and complain.

Good news is that it works, and resets the target volume list accordingly.

But now I have some decisions to make, and I wanted to ask the group for opinions.

How should this behave for automation?  If a user selects a workflow with a target volume of "/Volumes/Macintosh HD", and that workflow has a task that repartitions the disk so that there is no longer a "Macintosh HD" volume, what should the target be for all future tasks?  

Right now, I've avoided that problem by immediately breaking a workflow after a partition task is done (although I don't communicate that to the user at all - something to be fixed), so that an admin can't try to do something that might not work.

What should the automatic behavior be?  Should we continue to not allow partitioning to take place with other workflow tasks?  Should we add a new key like "target" to the partition task that sets the target for all future tasks to the specified volume?  Should we automatically choose the first partition specified in the "partition" array?

I'd love to hear some opinions / feedback on this.

--
--
Nick McSpadden
Client Systems Manager
Schools of the Sacred Heart, San Francisco

Graham Gilbert

unread,
May 14, 2015, 12:54:44 PM5/14/15
to Nick McSpadden, imag...@googlegroups.com
My gut reaction is to specify a target volume in the workflow (as your deciding what to call it in the workflow, it's not an unknown) or if it's not specified fall back to the select workflow screen. 

Graham Gilbert


--
You received this message because you are subscribed to the Google Groups "imagr-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to imagr-dev+...@googlegroups.com.
To post to this group, send email to imag...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/imagr-dev/CALCRC813eVEU3f-JebLD4rSfkJXnZBZEtd1EbFrjcC%2BnuhT6Rw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Gregory Neagle

unread,
May 14, 2015, 12:57:30 PM5/14/15
to imag...@googlegroups.com
Partitioning is a disk-level operation.
Imagr has a way to select _volumes_.
How does one select a _disk_ to be (re)partitioned?

-Greg

Nick McSpadden

unread,
May 14, 2015, 12:58:29 PM5/14/15
to Gregory Neagle, imag...@googlegroups.com
Right now, it picks the parent disk of the target volume.


For more options, visit https://groups.google.com/d/optout.



--

Gregory Neagle

unread,
May 14, 2015, 1:01:40 PM5/14/15
to imag...@googlegroups.com
Uninformed admins might not understand what is happening here and be very surprised when other volumes disappear…

BTW to whoever controls this group/list: it’s set so that email replies by default go to the _poster_ and not the list. That’s probably not ideal.

-Greg

Nick McSpadden

unread,
May 14, 2015, 1:14:01 PM5/14/15
to Graham Gilbert, imag...@googlegroups.com
So you'd want to see something like this:
<dict>
    <key>name</key>
    <string>Attempted Formatting</string>
    <key>description</key>
    <string>This will break everything you&apos;ve ever loved</string>
    <key>restart_action</key>
    <string>none</string>
    <key>bless_target</key>
    <false/>
    <key>components</key>
    <array>
        <dict>
            <key>type</key>
            <string>partition</string>
            <key>map</key>
            <string>GPTFormat</string>
            <key>target</key>
            <string>Macintosh HD</string>
            <key>partitions</key>
            <array>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>Macintosh HD</string>
                    <key>size</key>
                    <string>50%</string>
                </dict>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>Data</string>
                    <key>size</key>
                    <string>50%</string>
                </dict>
            </array>
        </dict>
    </array>
</dict>

Where the "target" key corresponds to a volume that will be used for all future tasks?

Nate

unread,
May 14, 2015, 1:21:54 PM5/14/15
to Gregory Neagle, imag...@googlegroups.com
Fixed the setting for imagr-dev. Replies should go to the group by default now.

Nate

Graham Gilbert

unread,
May 14, 2015, 1:25:10 PM5/14/15
to Nick McSpadden, imag...@googlegroups.com
Exactly. And I think the volume vs disk issue can be solved with being a bit more verbose in the main window with more info on attached disks and the volumes in them (sizes etc). 

Graham Gilbert

Nick McSpadden

unread,
May 14, 2015, 1:26:08 PM5/14/15
to Graham Gilbert, imag...@googlegroups.com
Okay, so how much sanity checking should be done?

What should happen if the admin specifies a target that doesn't actually exist?  Do we let the workflow fail naturally, or do we do an active check to see if the admin did something stupid and then complain?

Graham Gilbert

unread,
May 14, 2015, 1:28:26 PM5/14/15
to Nick McSpadden, imag...@googlegroups.com
As much as possible let diskutil do the barfing. 

Graham Gilbert

Graham Gilbert

unread,
May 14, 2015, 1:29:05 PM5/14/15
to Nick McSpadden, imag...@googlegroups.com
Plus the validation tool can do some checking. 

Graham Gilbert

Nick McSpadden

unread,
May 14, 2015, 1:41:25 PM5/14/15
to imag...@googlegroups.com
The problem is that diskutil won't be the one barfing if the admin specifies a target that doesn't exist for future tasks.

Scenario:
1) Workflow contains: Partition into "/Volumes/Hello", "/Volumes/Goodbye", with target set to "Macintosh HD."; Install Package on Target.
2) Partition task runs, divides existing drive into "/Volumes/Hello" and "/Volumes/Goodbye".  self.workVolume is now set to to "/Volumes/Macintosh HD" (which does not exist).
3) Install Package task runs and tries to install a package on "/Volumes/Macintosh HD".  This does not exist, so this task fails for a fairly unexpected reason (since none of the task functions validate their destination first).

The validation tool idea could work at addressing this to some degree.

Or perhaps we just have to assume that sometimes unexpected things happen and should just let it fail, and make it more clear in documentation what the "target" key is for?



For more options, visit https://groups.google.com/d/optout.

Graham Gilbert

unread,
May 14, 2015, 2:07:36 PM5/14/15
to imag...@googlegroups.com
That particular one is easy: within the partition definition, use future_target = true rather than specifying it elsewhere. 

Graham Gilbert


Nick McSpadden

unread,
May 14, 2015, 7:33:41 PM5/14/15
to imag...@googlegroups.com
I've added that functionality into the branch: 

Here's an example config_plist that describes the partitioning workflow, one with a target specified, and one without:

There's now a Boolean "target" key that can be specified in a partition that tells Imagr to use that as the target volume for all future workflow tasks.

<dict>
    <key>name</key>
    <string>Attempted Formatting</string>
    <key>description</key>
    <string>Partition into "First" + "Second", set "First" as target, install package</string>
    <key>restart_action</key>
    <string>none</string>
    <key>bless_target</key>
    <false/>
    <key>components</key>
    <array>
        <dict>
            <key>type</key>
            <string>partition</string>
            <key>map</key>
            <string>GPTFormat</string>
            <key>partitions</key>
            <array>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>First Partition</string>
                    <key>size</key>
                    <string>50%</string>
                    <key>target</key>
                    <true/>
                </dict>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>Second Partition</string>
                    <key>size</key>
                    <string>50%</string>
                </dict>
            </array>
        </dict>
        <dict>
            <key>type</key>
            <string>package</string>
            <key>url</key>
            <key>first_boot</key>
            <false/>
        </dict>
    </array>
</dict>

This task will partition the disk into two volumes, "First" and "Second", and then set the "First" as the target, and install a package on that volume.

If a "target" is not specified:
<dict>
    <key>name</key>
    <string>Attempted Formatting 2</string>
    <key>description</key>
    <string>Partitioning into "One" + "Two", don't set a target, try to install a package</string>
    <key>restart_action</key>
    <string>none</string>
    <key>bless_target</key>
    <false/>
    <key>components</key>
    <array>
        <dict>
            <key>type</key>
            <string>partition</string>
            <key>map</key>
            <string>GPTFormat</string>
            <key>partitions</key>
            <array>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>One</string>
                    <key>size</key>
                    <string>50%</string>
                </dict>
                <dict>
                    <key>format_type</key>
                    <string>Journaled HFS+</string>
                    <key>name</key>
                    <string>Two</string>
                    <key>size</key>
                    <string>50%</string>
                </dict>
            </array>
        </dict>
        <dict>
            <key>type</key>
            <string>package</string>
            <key>url</key>
            <key>first_boot</key>
            <false/>
        </dict>
    </array>
</dict>

After the partitioning task is complete, execution of the workflow halts and no further tasks in that workflow are processed.  Since no target was specified, there's no way for Imagr to know what to do next, so instead it goes back to the workflow selector and the user will have to do something else by manually choosing a volume from the list.

I've tested both cases and it behaves as expected.  My primary complaint is that it's a bit slow, and I'm providing no progress during this process - feedback is welcome on this.


For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages