diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
index 6d0b1e8..5349f65 100644
--- a/pyanaconda/installclass.py
+++ b/pyanaconda/installclass.py
@@ -74,10 +74,10 @@ class BaseInstallClass(object):
     def setDefaultPartitioning(self, storage):
         autorequests = [PartSpec(mountpoint="/", fstype=storage.defaultFSType,
                                  size=1024, maxSize=50*1024, grow=True,
-                                 btr=True, lv=True, encrypted=True),
+                                 btr=True, lv=True, thin=True, encrypted=True),
                         PartSpec(mountpoint="/home", fstype=storage.defaultFSType,
                                  size=500, grow=True, requiredSpace=50*1024,
-                                 btr=True, lv=True, encrypted=True)]
+                                 btr=True, lv=True, thin=True, encrypted=True)]
 
         bootreqs = platform.setDefaultPartitioning()
         if bootreqs:
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 7ebcf04..580b347 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -269,9 +269,9 @@ class Bootloader(commands.bootloader.F19_Bootloader):
         if self.timeout is not None:
             storage.bootloader.timeout = self.timeout
 
-        # Throw out drives specified that don't exist.
         disk_names = [d.name for d in storage.disks
                                 if not d.format.hidden and not d.protected]
+        # Throw out drives specified that don't exist.
         for drive in self.driveorder[:]:
             if drive not in disk_names:
                 log.warning("requested drive %s in boot drive order doesn't exist" % drive)
@@ -284,6 +284,8 @@ class Bootloader(commands.bootloader.F19_Bootloader):
                 raise KickstartValueError, formatErrorMsg(self.lineno,
                         msg="Requested boot drive %s doesn't exist" % self.bootDrive)
         else:
+            # FIXME: If the only drive contains install media there will be a
+            #        traceback.
             self.bootDrive = disk_names[0]
 
         spec = udev.udev_resolve_devspec(self.bootDrive)
diff --git a/pyanaconda/ui/gui/spokes/custom.glade b/pyanaconda/ui/gui/spokes/custom.glade
index bc92834..b99f0ee 100644
--- a/pyanaconda/ui/gui/spokes/custom.glade
+++ b/pyanaconda/ui/gui/spokes/custom.glade
@@ -1057,6 +1057,7 @@ use.  Try something else?</property>
                                           <item translatable="yes">BTRFS</item>
                                           <item translatable="yes">LVM</item>
                                           <item translatable="yes">RAID</item>
+                                          <item translatable="yes">LVM (Thin provisioned)</item>
                                         </items>
                                         <signal name="changed" handler="on_device_type_changed" swapped="no"/>
                                         <signal name="changed" handler="on_value_changed" swapped="no"/>
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index 6ee8ff5..f4535d0 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -48,6 +48,7 @@ from blivet.devicefactory import DEVICE_TYPE_BTRFS
 from blivet.devicefactory import DEVICE_TYPE_PARTITION
 from blivet.devicefactory import DEVICE_TYPE_MD
 from blivet.devicefactory import DEVICE_TYPE_DISK
+from blivet.devicefactory import DEVICE_TYPE_LVM_THINP
 from blivet.devicefactory import get_raid_level
 from blivet.devicefactory import SIZE_POLICY_AUTO
 from blivet.devicefactory import SIZE_POLICY_MAX
@@ -111,6 +112,7 @@ empty_name_msg = N_("Please enter a valid name.")
 invalid_name_msg = N_("That name is invalid. Try something else?")
 
 container_type_names = {DEVICE_TYPE_LVM: lvm_container_name,
+                        DEVICE_TYPE_LVM_THINP: lvm_container_name,
                         DEVICE_TYPE_BTRFS: btrfs_container_name}
 
 MOUNTPOINT_OK = 0
@@ -124,6 +126,7 @@ mountpoint_validation_msgs = {MOUNTPOINT_OK: "",
                               MOUNTPOINT_EMPTY: empty_mountpoint_msg}
 
 DEVICE_TEXT_LVM = N_("LVM")
+DEVICE_TEXT_LVM_THINP = N_("LVM (Thin provisioned)")
 DEVICE_TEXT_MD = N_("RAID")
 DEVICE_TEXT_PARTITION = N_("Standard Partition")
 DEVICE_TEXT_BTRFS = N_("BTRFS")
@@ -132,7 +135,8 @@ DEVICE_TEXT_DISK = N_("Disk")
 device_text_map = {DEVICE_TYPE_LVM: DEVICE_TEXT_LVM,
                    DEVICE_TYPE_MD: DEVICE_TEXT_MD,
                    DEVICE_TYPE_PARTITION: DEVICE_TEXT_PARTITION,
-                   DEVICE_TYPE_BTRFS: DEVICE_TEXT_BTRFS}
+                   DEVICE_TYPE_BTRFS: DEVICE_TEXT_BTRFS,
+                   DEVICE_TYPE_LVM_THINP: DEVICE_TEXT_LVM_THINP}
 
 partition_only_format_types = ["efi", "hfs+", "prepboot", "biosboot",
                                "appleboot"]
@@ -526,7 +530,7 @@ class ContainerDialog(GUIObject):
 
     def _raid_level_visible(self, model, itr, user_data):
         # This is weird because for lvm's container-wide raid we use md.
-        if self.device_type == DEVICE_TYPE_LVM:
+        if self.device_type in (DEVICE_TYPE_LVM, DEVICE_TYPE_LVM_THINP):
             return model[itr][4]
         elif self.device_type == DEVICE_TYPE_BTRFS:
             return model[itr][3]
@@ -551,7 +555,7 @@ class ContainerDialog(GUIObject):
         raid_label = self.builder.get_object("containerRaidLevelLabel")
         raid_combo = self.builder.get_object("containerRaidLevelCombo")
 
-        if self.device_type not in [DEVICE_TYPE_LVM, DEVICE_TYPE_BTRFS]:
+        if self.device_type not in [DEVICE_TYPE_LVM, DEVICE_TYPE_BTRFS, DEVICE_TYPE_LVM_THINP]:
             map(really_hide, [raid_label, raid_combo])
             return
 
@@ -611,6 +615,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         self._device_container_size = SIZE_POLICY_AUTO
         self._device_name_dict = {DEVICE_TYPE_LVM: None,
                                   DEVICE_TYPE_MD: None,
+                                  DEVICE_TYPE_LVM_THINP: None,
                                   DEVICE_TYPE_PARTITION: "",
                                   DEVICE_TYPE_BTRFS: "",
                                   DEVICE_TYPE_DISK: ""}
@@ -1312,6 +1317,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
                                          device=_device,
                                          selector=selector)
                 except StorageError as e:
+                    raise
                     log.error("factoryDevice failed: %s" % e)
                     # the factory's error handling has replaced all of the
                     # devices with copies, so update the selectors' devices
@@ -1584,6 +1590,8 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
             device_type = DEVICE_TYPE_BTRFS
         elif device_type_text == _(DEVICE_TEXT_DISK):
             device_type = DEVICE_TYPE_DISK
+        elif device_type_text == _(DEVICE_TEXT_LVM_THINP):
+            device_type = DEVICE_TYPE_LVM_THINP
         else:
             log.error("unknown device type: '%s'" % device_type_text)
 
@@ -1749,6 +1757,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         btrfs_pos = None
         partition_pos = None
         lvm_pos = None
+        thinp_pos = None
         for idx, itr in enumerate(self._typeCombo.get_model()):
             if itr[0] == _(DEVICE_TEXT_BTRFS):
                 btrfs_pos = idx
@@ -1760,12 +1769,15 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
                 lvm_pos = idx
             elif itr[0] == _(DEVICE_TEXT_DISK):
                 disk_pos = idx
+            elif itr[0] == _(DEVICE_TEXT_LVM_THINP):
+                thinp_pos = idx
 
         device_type = devicefactory.get_device_type(device)
         raid_level = devicefactory.get_raid_level(device)
         type_index_map = {DEVICE_TYPE_PARTITION: partition_pos,
                           DEVICE_TYPE_BTRFS: btrfs_pos,
                           DEVICE_TYPE_LVM: lvm_pos,
+                          DEVICE_TYPE_LVM_THINP: thinp_pos,
                           DEVICE_TYPE_MD: md_pos,
                           DEVICE_TYPE_DISK: disk_pos}
 
@@ -1773,7 +1785,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
             if _type == device_type:
                 self._device_name_dict[_type] = device_name
                 continue
-            elif _type not in (DEVICE_TYPE_LVM, DEVICE_TYPE_MD, DEVICE_TYPE_BTRFS):
+            elif _type not in (DEVICE_TYPE_LVM, DEVICE_TYPE_MD, DEVICE_TYPE_BTRFS, DEVICE_TYPE_LVM_THINP):
                 continue
 
             swap = (device.format.type == "swap")
@@ -1900,6 +1912,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
             mountpoint = None
 
         device_type_from_autopart = {AUTOPART_TYPE_LVM: DEVICE_TYPE_LVM,
+                                     AUTOPART_TYPE_LVM_THINP: DEVICE_TYPE_LVM_THINP,
                                      AUTOPART_TYPE_PLAIN: DEVICE_TYPE_PARTITION,
                                      AUTOPART_TYPE_BTRFS: DEVICE_TYPE_BTRFS}
         device_type = device_type_from_autopart[self.data.autopart.type]
@@ -2027,7 +2040,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         container = None
         if hasattr(device, "vg"):
             container = device.vg
-            device_type = DEVICE_TYPE_LVM
+            device_type = devicefactory.get_device_type(device)
         elif hasattr(device, "volume"):
             container = device.volume
             device_type = DEVICE_TYPE_BTRFS
@@ -2159,8 +2172,8 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         if device.exists:
             return
 
-        if self._get_current_device_type() == DEVICE_TYPE_LVM:
-            # LVM disk set management happens through VG edit on RHS
+        if self._get_current_device_type() in (DEVICE_TYPE_LVM, DEVICE_TYPE_LVM_THINP, DEVICE_TYPE_BTRFS):
+            # disk set management happens through container edit on RHS
             return
 
         self.clear_errors()
@@ -2408,7 +2421,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         self._applyButton.set_sensitive(False)
         self._configButton.set_sensitive(not selector._device.exists and
                                          not selector._device.protected and
-                                         devicefactory.get_device_type(selector._device) != DEVICE_TYPE_LVM)
+                                         devicefactory.get_device_type(selector._device) in (DEVICE_TYPE_PARTITION, DEVICE_TYPE_MD))
         self._removeButton.set_sensitive(not selector._device.protected)
         return True
 
@@ -2547,7 +2560,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         container_combo = self.builder.get_object("containerCombo")
         container_label = self.builder.get_object("containerLabel")
         container_size_policy = SIZE_POLICY_AUTO
-        if device_type in (DEVICE_TYPE_LVM, DEVICE_TYPE_BTRFS):
+        if device_type in (DEVICE_TYPE_LVM, DEVICE_TYPE_BTRFS, DEVICE_TYPE_LVM_THINP):
             # set up the vg widgets and then bail out
             if devicefactory.get_device_type(device) == device_type:
                 _device = device
@@ -2566,10 +2579,10 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
             container_type_text = container_type_names[device_type]
             container_label.set_text(container_type_text.title())
             container_combo.remove_all()
-            if device_type == DEVICE_TYPE_LVM:
-                containers = self.__storage.vgs
-            else:
+            if device_type == DEVICE_TYPE_BTRFS:
                 containers = self.__storage.btrfsVolumes
+            else:
+                containers = self.__storage.vgs
 
             default_seen = False
             for c in containers:
@@ -2640,7 +2653,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
 
         # lvm uses the RHS to set disk set. no foolish minds here.
         exists = self._current_selector and self._current_selector._device.exists
-        self._configButton.set_sensitive(not exists and new_type != DEVICE_TYPE_LVM)
+        self._configButton.set_sensitive(not exists and new_type not in (DEVICE_TYPE_LVM, DEVICE_TYPE_LVM_THINP, DEVICE_TYPE_BTRFS))
 
         # this has to be done before calling populate_raid since it will need
         # the raid level combo to contain the relevant raid levels for the new
@@ -2650,7 +2663,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
         self._populate_raid(raid_level)
         self._populate_container()
 
-        fancy_set_sensitive(self._nameEntry, new_type in (DEVICE_TYPE_BTRFS, DEVICE_TYPE_LVM, DEVICE_TYPE_MD))
+        fancy_set_sensitive(self._nameEntry, new_type in (DEVICE_TYPE_BTRFS, DEVICE_TYPE_LVM, DEVICE_TYPE_MD, DEVICE_TYPE_LVM_THINP))
         self._nameEntry.set_text(self._device_name_dict[new_type])
         fancy_set_sensitive(self._sizeEntry, new_type != DEVICE_TYPE_BTRFS)
 
diff --git a/pyanaconda/ui/gui/spokes/filter.py b/pyanaconda/ui/gui/spokes/filter.py
index 808e67f..ec2158b 100644
--- a/pyanaconda/ui/gui/spokes/filter.py
+++ b/pyanaconda/ui/gui/spokes/filter.py
@@ -203,7 +203,7 @@ class SearchPage(FilterPage):
 
     def visible_func(self, model, itr, *args):
         obj = DiskStoreRow._make(model[itr])
-        device = self.storage.devicetree.getDeviceByName(obj.name)
+        device = self.storage.devicetree.getDeviceByName(obj.name, hidden=True)
         return self._filter_func(device)
 
 class MultipathPage(FilterPage):
@@ -270,7 +270,7 @@ class MultipathPage(FilterPage):
             return False
 
         obj = DiskStoreRow._make(model[itr])
-        device = self.storage.devicetree.getDeviceByName(obj.name)
+        device = self.storage.devicetree.getDeviceByName(obj.name, hidden=True)
         return self.ismember(device) and self._filter_func(device)
 
 class OtherPage(FilterPage):
@@ -357,7 +357,7 @@ class OtherPage(FilterPage):
 
     def visible_func(self, model, itr, *args):
         obj = DiskStoreRow._make(model[itr])
-        device = self.storage.devicetree.getDeviceByName(obj.name)
+        device = self.storage.devicetree.getDeviceByName(obj.name, hidden=True)
         return self.ismember(device) and self._filter_func(device)
 
 class RaidPage(FilterPage):
@@ -374,7 +374,7 @@ class RaidPage(FilterPage):
             return False
 
         obj = DiskStoreRow._make(model[itr])
-        device = self.storage.devicetree.getDeviceByName(obj.name)
+        device = self.storage.devicetree.getDeviceByName(obj.name, hidden=True)
         return self.ismember(device)
 
 class ZPage(FilterPage):
@@ -394,7 +394,7 @@ class ZPage(FilterPage):
 
     def visible_func(self, model, itr, *args):
         obj = DiskStoreRow._make(model[itr])
-        device = self.storage.devicetree.getDeviceByName(obj.name)
+        device = self.storage.devicetree.getDeviceByName(obj.name, hidden=True)
         return self.ismember(device)
 
 class FilterSpoke(NormalSpoke):
@@ -417,7 +417,7 @@ class FilterSpoke(NormalSpoke):
 
     def apply(self):
         onlyuse = self.selected_disks[:]
-        for disk in [d for d in self.storage.disks if d.name in onlyuse]:
+        for disk in [d for d in self.disks if d.name in onlyuse]:
             onlyuse.extend([d.name for d in disk.ancestors
                                         if d.name not in onlyuse])
 
diff --git a/pyanaconda/ui/gui/spokes/storage.glade b/pyanaconda/ui/gui/spokes/storage.glade
index 24c7a4b..cefed27 100644
--- a/pyanaconda/ui/gui/spokes/storage.glade
+++ b/pyanaconda/ui/gui/spokes/storage.glade
@@ -186,11 +186,12 @@
                   <object class="GtkComboBoxText" id="options1_combo">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="active">2</property>
+                    <property name="active">3</property>
                     <items>
                       <item translatable="yes">Standard Partition</item>
                       <item translatable="yes">BTRFS</item>
                       <item translatable="yes">LVM</item>
+                      <item translatable="yes">LVM Thin Provisioning</item>
                     </items>
                     <signal name="changed" handler="on_type_changed" swapped="no"/>
                   </object>
@@ -485,11 +486,12 @@
                   <object class="GtkComboBoxText" id="options2_combo">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="active">2</property>
+                    <property name="active">3</property>
                     <items>
                       <item translatable="yes">Standard Partition</item>
                       <item translatable="yes">BTRFS</item>
                       <item translatable="yes">LVM</item>
+                      <item translatable="yes">LVM Thin Provisioning</item>
                     </items>
                     <signal name="changed" handler="on_type_changed" swapped="no"/>
                   </object>
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 501d9b1..d86fa69 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -549,7 +549,7 @@ class StorageSpoke(NormalSpoke, StorageChecker):
         # those selected in the filter UI are displayed.  This means refresh
         # needs to know to create and destroy overviews as appropriate.
         for name in self.data.ignoredisk.onlyuse:
-            obj = self.storage.devicetree.getDeviceByName(name)
+            obj = self.storage.devicetree.getDeviceByName(name, hidden=True)
             if isLocalDisk(obj):
                 continue
 
