Skip to content

Commit

Permalink
Add a method to find the Btrfs default_subvol
Browse files Browse the repository at this point in the history
  • Loading branch information
imobachgs committed Nov 3, 2016
1 parent 00aa17f commit b745e19
Show file tree
Hide file tree
Showing 5 changed files with 347 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/modules/FileSystems.rb
Expand Up @@ -31,6 +31,7 @@
# $Id$
require "storage"
require "yast"
require "yast2/execute"

module Yast
class FileSystemsClass < Module
Expand All @@ -46,6 +47,7 @@ def main
Yast.import "Encoding"
Yast.import "Stage"
Yast.import "StorageInit"
Yast.import "ProductFeatures"

@conv_fs = {
"def_sym" => :unknown,
Expand Down Expand Up @@ -2054,6 +2056,47 @@ def default_subvol
@default_subvol
end

# Try to find the default subvolume name in the target system
#
# * Root partition takes precedence
# * Not supported: more than 1 Btrfs filesystems, one using
# a '@' default subvolume and the other using ''. In that case,
# default_subvolume is set to product's default.
#
# @return [String,nil] Default subvolume from the target system
def default_subvol_from_filesystem
parts = Storage.GetTargetMap.map { |_k, d| d.fetch("partitions") }.flatten.compact
btrfs_parts = parts.select { |p| p["used_fs"] == :btrfs }
default_subvol_names = btrfs_parts.reduce({}) do |memo, part|
memo[part["mount"]] = btrfs_subvol_name_for(part) unless part["mount"].nil?
memo
end

# Root takes precedence
return default_subvol_names["/"] if default_subvol_names.has_key?("/")

# If all has the same default subvolume name
found_names = default_subvol_names.values.uniq
return found_names.first if found_names.size == 1

# If there are different values, fallback to product's default
default_subvol_from_product
end

# Default subvol name from product
#
# @return [String] Default subvolume name
def default_subvol_from_product
ProductFeatures.GetStringFeature("partitioning", "btrfs_default_subvolume")
end

protected

def btrfs_subvol_name_for(partition)
ret = Yast::Execute.on_target("btrfs", "subvol", "list", partition["mount"], stdout: :capture)
ret.split("\n").first =~ /.+ @\z/ ? "@" : ""
end

publish :variable => :conv_fs, :type => "map <string, any>"
publish :variable => :possible_root_fs, :type => "const list <symbol>"
publish :function => :system_m_points, :type => "list <string> ()"
Expand Down
64 changes: 64 additions & 0 deletions test/filesystems_test.rb
@@ -0,0 +1,64 @@
#!/usr/bin/env rspec

require_relative "spec_helper"

Yast.import "FileSystems"
Yast.import "Storage"

describe Yast::FileSystems do
subject { Yast::FileSystems }

describe "#default_subvol_from_filesystem" do
let(:target_map) { YAML.load_file(File.join(FIXTURES_PATH, "subvolumes.yml")) }
let(:btrfs_list) { File.read(File.join(FIXTURES_PATH, "btrfs_list.out")) }
let(:btrfs_list_no_at) { File.read(File.join(FIXTURES_PATH, "btrfs_list_no_at.out")) }
let(:default_subvol) { "@" }

before do
allow(Yast::Storage).to receive(:GetTargetMap).and_return(target_map)
allow(Yast::ProductFeatures).to receive(:GetStringFeature)
.with("partitioning", "btrfs_default_subvolume").and_return(default_subvol)
end

context "when root partition uses the default subvolume name (@)" do
let(:btrfs_list) { File.read(File.join(FIXTURES_PATH, "btrfs_list.out")) }

it "returns the default subvolume name" do
allow(Yast::Execute).to receive(:on_target).with("btrfs", "subvol", "list", "/", anything)
.and_return(btrfs_list)
allow(Yast::Execute).to receive(:on_target).with("btrfs", "subvol", "list", "/srv", anything)
.and_return(btrfs_list_no_at)
expect(subject.default_subvol_from_filesystem).to eq(default_subvol)
end
end

context "when root partitions does not use the default subvolume name (@)" do
before do
allow(Yast::Execute).to receive(:on_target).with("btrfs", "subvol", "list", "/", anything)
.and_return(btrfs_list_no_at)
end

context "but all partitions uses the same subvolume name" do
before do
allow(Yast::Execute).to receive(:on_target).with("btrfs", "subvol", "list", "/srv", anything)
.and_return(btrfs_list_no_at)
end

it "returns the used name ('' in this case)" do
expect(subject.default_subvol_from_filesystem).to eq("")
end
end

context "and partitions uses different subvolume names" do
before do
allow(Yast::Execute).to receive(:on_target).with("btrfs", "subvol", "list", "/srv", anything)
.and_return(btrfs_list)
end

it "returns the distribution default" do
expect(subject.default_subvol_from_filesystem).to eq("")
end
end
end
end
end
28 changes: 28 additions & 0 deletions test/fixtures/btrfs_list.out
@@ -0,0 +1,28 @@
ID 257 gen 34 top level 5 path @
ID 258 gen 51 top level 257 path @/.snapshots
ID 259 gen 88 top level 258 path @/.snapshots/1/snapshot
ID 260 gen 44 top level 257 path @/boot/grub2/i386-pc
ID 261 gen 15 top level 257 path @/boot/grub2/x86_64-efi
ID 262 gen 44 top level 257 path @/home
ID 263 gen 51 top level 257 path @/opt
ID 264 gen 50 top level 257 path @/srv
ID 265 gen 88 top level 257 path @/tmp
ID 266 gen 64 top level 257 path @/usr/local
ID 267 gen 38 top level 257 path @/var/crash
ID 268 gen 22 top level 257 path @/var/lib/mailman
ID 269 gen 88 top level 257 path @/var/lib/named
ID 270 gen 24 top level 257 path @/var/lib/pgsql
ID 271 gen 88 top level 257 path @/var/log
ID 272 gen 38 top level 257 path @/var/opt
ID 273 gen 84 top level 257 path @/var/spool
ID 274 gen 51 top level 257 path @/var/tmp
ID 275 gen 30 top level 257 path @/mysubvol
ID 276 gen 47 top level 275 path @/mysubvol/mysubsubvol
ID 277 gen 32 top level 257 path @/myothersubvol
ID 278 gen 47 top level 277 path @/myothersubvol/myothersubsubvol
ID 279 gen 33 top level 257 path @/nocow
ID 280 gen 35 top level 257 path @/myvol
ID 282 gen 40 top level 259 path var/lib/machines
ID 283 gen 48 top level 258 path @/.snapshots/2/snapshot
ID 284 gen 49 top level 258 path @/.snapshots/3/snapshot
ID 285 gen 50 top level 258 path @/.snapshots/4/snapshot
27 changes: 27 additions & 0 deletions test/fixtures/btrfs_list_no_at.out
@@ -0,0 +1,27 @@
ID 257 gen 48 top level 5 path .snapshots
ID 258 gen 92 top level 257 path .snapshots/1/snapshot
ID 259 gen 41 top level 5 path boot/grub2/i386-pc
ID 260 gen 12 top level 5 path boot/grub2/x86_64-efi
ID 261 gen 41 top level 5 path home
ID 262 gen 49 top level 5 path opt
ID 263 gen 47 top level 5 path srv
ID 264 gen 91 top level 5 path tmp
ID 265 gen 61 top level 5 path usr/local
ID 266 gen 35 top level 5 path var/crash
ID 267 gen 19 top level 5 path var/lib/mailman
ID 268 gen 89 top level 5 path var/lib/named
ID 269 gen 21 top level 5 path var/lib/pgsql
ID 270 gen 90 top level 5 path var/log
ID 271 gen 35 top level 5 path var/opt
ID 272 gen 91 top level 5 path var/spool
ID 273 gen 48 top level 5 path var/tmp
ID 274 gen 27 top level 5 path mysubvol
ID 275 gen 44 top level 274 path mysubvol/mysubsubvol
ID 276 gen 29 top level 5 path @/myothersubvol
ID 277 gen 44 top level 276 path @/myothersubvol/myothersubsubvol
ID 278 gen 30 top level 5 path nocow
ID 279 gen 32 top level 5 path myvol
ID 281 gen 37 top level 258 path var/lib/machines
ID 282 gen 45 top level 257 path .snapshots/2/snapshot
ID 283 gen 46 top level 257 path .snapshots/3/snapshot
ID 284 gen 47 top level 257 path .snapshots/4/snapshot
185 changes: 185 additions & 0 deletions test/fixtures/subvolumes.yml
@@ -0,0 +1,185 @@
---
"/dev/vda":
unique: KSbE.Fxp0d3BezAE
bus: None
device: "/dev/vda"
bios_id: '0x80'
driver: virtio-pci
driver_module: virtio_pci
partitions:
- device: "/dev/vda1"
name: vda1
used_by:
- type: :UB_BTRFS
device: 8e6e04a4-758f-4d43-bab8-6b3dca3d31e2
used_by_type: :UB_BTRFS
used_by_device: 8e6e04a4-758f-4d43-bab8-6b3dca3d31e2
size_k: 13925376
used_fs: :btrfs
detected_fs: :btrfs
fstopt: defaults
nr: 2
fsid: 131
fstype: Linux native
region:
- 93
- 1734
type: :primary
boot: true
subvol:
- name: "@"
- name: "@/.snapshots"
- name: "@/.snapshots/1/snapshot"
- name: "@/home"
- name: "@/var/log"
- name: "@/var/lib/pgsql"
- name: "@/myvol"
nocow: true
- name: "@/.snapshots/1/snapshot/var/lib/machines"
- name: "@/.snapshots/2/snapshot"
- name: "@/.snapshots/3/snapshot"
- name: "@/.snapshots/4/snapshot"
uuid: 8e6e04a4-758f-4d43-bab8-6b3dca3d31e2
mount: "/"
mountby: :uuid
size_k: 14680064
cyl_size: 8225280
cyl_count: 1827
sector_size: 512
label: msdos
name: vda
max_logical: 255
max_primary: 4
type: :CT_DISK
transport: :unknown
used_by_type: :UB_NONE
used_by_device: ''
dasd_format: 0
dasd_type: 0
"/dev/vdb":
unique: KSbE.Fxp0d3BezAE
bus: None
device: "/dev/vdb"
bios_id: '0x80'
driver: virtio-pci
driver_module: virtio_pci
partitions:
- device: "/dev/vdb1"
name: vdb1
used_by_type: :UB_NONE
used_by_device: ''
size_k: 753664
used_fs: :swap
detected_fs: :swap
mount: swap
mountby: :uuid
fstopt: defaults
uuid: 3fc06e37-d6b6-4411-baf3-2920cdf19fa4
nr: 1
fsid: 130
fstype: Linux swap
region:
- 0
- 94
type: :primary
- device: "/dev/vdb2"
name: vdb2
used_by:
- type: :UB_BTRFS
device: 862e2cbf-0501-48a1-85a3-142bfe3ab51b
used_by_type: :UB_BTRFS
used_by_device: 862e2cbf-0501-48a1-85a3-142bfe3ab51b
size_k: 13925376
used_fs: :btrfs
detected_fs: :btrfs
fstopt: defaults
nr: 2
fsid: 131
fstype: Linux native
region:
- 93
- 1734
type: :primary
boot: true
subvol:
- name: shared
- name: www
uuid: 862e2cbf-0501-48a1-85a3-142bfe3ab51b
mount: "/srv"
mountby: :uuid
size_k: 14680064
cyl_size: 8225280
cyl_count: 1827
sector_size: 512
label: msdos
name: vdb
max_logical: 255
max_primary: 4
type: :CT_DISK
transport: :unknown
used_by_type: :UB_NONE
used_by_device: ''
dasd_format: 0
dasd_type: 0
"/dev/btrfs":
device: "/dev/btrfs"
name: btrfs
used_by_type: :UB_NONE
used_by_device: ''
type: :CT_BTRFS
partitions: []
"/dev/tmpfs":
device: "/dev/tmpfs"
name: tmpfs
used_by_type: :UB_NONE
used_by_device: ''
type: :CT_TMPFS
partitions:
- device: tmpfs
name: none
used_by_type: :UB_NONE
used_by_device: ''
size_k: 233312
used_fs: :tmpfs
detected_fs: :tmpfs
mount: "/dev/shm"
mountby: :uuid
ignore_fstab: true
type: :tmpfs
fstype: TMPFS
- device: tmpfs
name: none
used_by_type: :UB_NONE
used_by_device: ''
size_k: 233312
used_fs: :tmpfs
detected_fs: :tmpfs
mount: "/run"
mountby: :uuid
ignore_fstab: true
type: :tmpfs
fstype: TMPFS
- device: tmpfs
name: none
used_by_type: :UB_NONE
used_by_device: ''
size_k: 233312
used_fs: :tmpfs
detected_fs: :tmpfs
mount: "/sys/fs/cgroup"
mountby: :uuid
ignore_fstab: true
type: :tmpfs
fstype: TMPFS
- device: tmpfs
name: none
used_by_type: :UB_NONE
used_by_device: ''
size_k: 46664
used_fs: :tmpfs
detected_fs: :tmpfs
mount: "/run/user/0"
mountby: :uuid
ignore_fstab: true
type: :tmpfs
fstype: TMPFS

0 comments on commit b745e19

Please sign in to comment.