-
Notifications
You must be signed in to change notification settings - Fork 19
/
fstab_options.rb
968 lines (804 loc) · 27.5 KB
/
fstab_options.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
# Copyright (c) [2017-2021] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.
require "yast"
require "cwm"
require "y2storage"
require "y2partitioner/dialogs/fstab_options"
Yast.import "Popup"
module Y2Partitioner
# Partitioner widgets
module Widgets
include Yast::Logger
# The fstab options are mostly checkboxes and combo boxes that share some
# common methods, so this is a mixin for that shared code.
module FstabCommon
# @param controller [Y2Partitioner::Actions::Controllers:Filesystem]
def initialize(controller)
super()
textdomain "storage"
@controller = controller
end
# @macro seeAbstractWidget
def init
init_regexp if self.class.const_defined?("REGEXP")
end
# Not all the fstab options are supported by all the filesystems so each
# widget is able to check if the current filesystem is supported
# explicitely or checking if the values it is responsible for are
# supported by the filesystem.
def supported_by_filesystem?
return false if filesystem.nil?
if self.class.const_defined?("SUPPORTED_FILESYSTEMS")
self.class::SUPPORTED_FILESYSTEMS
.include?(filesystem.type.to_sym)
elsif self.class.const_defined?("VALUES")
self.class::VALUES.all? do |v|
filesystem.type.supported_fstab_options.include?(v)
end
else
false
end
end
# @param widget [CWM::AbstractWidget]
# @return [CWM::WidgetTerm]
def to_ui_term(widget)
return Empty() unless widget.supported_by_filesystem?
Left(widget)
end
# @param widget [CWM::AbstractWidget]
# @return [Array<CWM::WidgetTerm>]
def ui_term_with_vspace(widget)
return [Empty()] unless widget.supported_by_filesystem?
[Left(widget), VSpacing(1)]
end
# Removes from the MountPoint object the options that not longer apply
def delete_fstab_option!(option)
# The options can only be modified using MountPoint#mount_options=
mount_point.mount_options = mount_point.mount_options.grep_v(option)
end
# Adds new options to the MountPoint object
def add_fstab_options(*options)
# The options can only be modified using MountPoint#mount_options=
mount_point.mount_options = mount_point.mount_options + options
end
alias_method :add_fstab_option, :add_fstab_options
private
# Current devicegraph
#
# @return [Y2Storage::Devicegraph]
def working_graph
DeviceGraphs.instance.current
end
# Filesystem currently being edited
#
# @return [Y2Storage::Filesystems::Base]
def filesystem
@controller.filesystem
end
# Check if the underlying filesystem is a btrfs.
#
# @return [Boolean]
def btrfs?
@controller.btrfs?
end
# Mount point of the current filesystem
#
# @return [Y2Storage::MountPoint]
def mount_point
@controller.mount_point
end
# Mount path of the current filesystem
#
# @return [String]
def mount_path
return nil if filesystem.mount_point.nil?
filesystem.mount_point.path
end
# Common regexp checkbox widgets init.
def init_regexp
i = mount_point.mount_options.index { |o| o =~ self.class::REGEXP }
self.value =
if i
mount_point.mount_options[i].gsub(self.class::REGEXP, "")
else
self.class::DEFAULT
end
end
end
# Push button that launch a dialog to set the fstab options
class FstabOptionsButton < CWM::PushButton
include FstabCommon
# @macro seeAbstractWidget
def label
_("Fstab Options...")
end
# @macro seeAbstractWidget
def handle
log.info("fstab_options before dialog: #{mount_point.mount_options}")
Dialogs::FstabOptions.new(@controller).run
log.info("fstab_options after dialog: #{mount_point.mount_options}")
nil
end
end
# FIXME: The help handle does not work without wizard
# Main widget for set all the available options for a particular filesystem
class FstabOptions < CWM::CustomWidget
include FstabCommon
# Filesystem types that can be configured
SUPPORTED_FILESYSTEMS = [:btrfs, :ext2, :ext3, :ext4].freeze
def initialize(controller)
super # to pass controller to FstabCommon
@controller = controller
self.handle_all_events = true
end
# @macro seeAbstractWidget
def init
@contents = nil
@values = nil
@regexps = nil
disable if !supported_by_filesystem?
end
# @macro seeCustomWidget
def contents
@contents ||=
VBox(
Left(MountBy.new(@controller)),
VSpacing(1),
* ui_term_with_vspace(VolumeLabel.new(@controller, self)),
Left(GeneralOptions.new(@controller)),
Left(FilesystemsOptions.new(@controller)),
* ui_term_with_vspace(JournalOptions.new(@controller)),
Left(ArbitraryOptions.new(@controller, self))
)
end
# Return an array of all VALUES of all widgets in this tree.
# @return [Array<String>]
def values
@values ||= widgets.each_with_object([]) do |widget, values|
next unless widget.class.const_defined?("VALUES")
values.concat(widget.class::VALUES)
end.uniq
end
# Return an array of all REGEXPs of all widgets in this tree.
# @return [Array<Regexp>]
def regexps
@regexps ||= widgets.each_with_object([]) do |widget, regexps|
next unless widget.class.const_defined?("REGEXP")
regexps << widget.class::REGEXP
end.uniq
end
def widgets
Yast::CWM.widgets_in_contents([self])
end
end
# Input field to set the partition Label
class VolumeLabel < CWM::InputField
include FstabCommon
# Constructor
#
# @param controller [Actions::Controllers:Filesystem]
# @param parent_widget [Widgets::FstabOptions]
def initialize(controller, parent_widget)
super(controller)
@parent_widget = parent_widget
end
# @see FstabCommon::supported_by_filesystem?
#
# @return [Boolean]
def supported_by_filesystem?
filesystem.supports_label?
end
# @macro seeAbstractWidget
def label
_("Volume &Label")
end
# @macro seeAbstractWidget
def store
filesystem.label = value
end
# @macro seeAbstractWidget
def init
self.value = filesystem.label
Yast::UI.ChangeWidget(Id(widget_id), :ValidChars, valid_chars)
Yast::UI.ChangeWidget(Id(widget_id), :InputMaxLength, input_max_length)
disable unless can_set_volume_label?
end
# Validates uniqueness of the given label. The presence of the label is also
# checked when the filesystem is set to be mounted by label.
#
# @note An error popup message is presented when it is needed.
#
# @return [Boolean]
def validate
presence_validation && uniqueness_validation
end
private
# @return [Widgets::FstabOptions]
attr_reader :parent_widget
# Check if the volume label can be set.
#
# @return [Boolean]
def can_set_volume_label?
return true unless @controller.mounted_in_system_graph?
blk_dev = @controller.blk_device_name
fs_type = @controller.filesystem_type
log.info("#{blk_dev} type #{fs_type} is mounted")
# Can't change the volume label for a mounted Btrfs or swap (bsc#1211337)
!btrfs? && !swap?
end
def btrfs?
@controller.filesystem_type.is?(:btrfs)
end
def swap?
@controller.filesystem_type.is?(:swap)
end
# Checks whether a label is given when the filesystem is mounted by label
#
# @note An error popup is presented when the filesystem is mounted by label
# but a label is not given.
#
# @return [Boolean]
def presence_validation
return true unless mounted_by_label?
return true unless value.empty?
# TRANSLATORS: Error messagge when the label is not given.
Yast::Popup.Error(_("Provide a volume label to mount by label."))
focus
false
end
# Checks whether a filesystem already exists with the given label
#
# @note An error popup is presented when other filesystem has the given label.
#
# @return [Boolean]
def uniqueness_validation
return true unless duplicated_label?
# TRANSLATORS: Error message when the given label is already in use.
Yast::Popup.Error(_("This volume label is already in use. Select a different one."))
focus
false
end
# Whether the mount by label option is selected
#
# @return [Boolean] true if mount by label is selected; false otherwise.
def mounted_by_label?
mount_by_widget.value == :label
end
# Whether the given label is duplicated
#
# @return [Boolean] true if the label is duplicated; false otherwise.
def duplicated_label?
return false if value.empty?
working_graph.filesystems.any? do |fs|
next false if fs.sid == filesystem.sid
next false unless fs.respond_to?(:label) # NFS doesn't support labels
fs.label == value
end
end
# Widget to select the mount by option
#
# @return [MountBy]
def mount_by_widget
parent_widget.widgets.find { |w| w.is_a?(Y2Partitioner::Widgets::MountBy) }
end
# Sets the focus into this widget
def focus
Yast::UI.SetFocus(Id(widget_id))
end
# Return the valid characters for this input field
#
# @return [String]
def valid_chars
filesystem.type.label_valid_chars
end
# Return the maximum length of the input (the number of characters) for
# this input field
#
# @return [Integer]
def input_max_length
filesystem.max_labelsize
end
end
# A combobox to select the type of identifier to be used for mount
# the specific device (UUID, Label, Path...)
class MountBy < CWM::ComboBox
include FstabCommon
# @macro seeAbstractWidget
def label
_("Mount in /etc/fstab By")
end
# @macro seeAbstractWidget
def init
select_default_mount_by
end
# @macro seeAbstractWidget
def store
mount_point.mount_by = selected_mount_by
end
# @macro seeCustomWidget
def items
# CWM does not support symbols for entries in ComboBoxes
# contrary to libyui. Otherwise a few conversations between
# string and symbol below could be avoided.
suitable = mount_point.suitable_mount_bys(label: true, encryption:
@controller.encrypt).map { |mount_by| mount_by.to_sym.to_s }
[
["device", _("Device Name")],
["id", _("Device ID")],
["path", _("Device Path")],
["uuid", _("UUID")],
["label", _("Volume Label")]
].select { |item| suitable.include? item[0] }
end
private
def selected_mount_by
Y2Storage::Filesystems::MountByType.find(value.to_sym)
end
def select_default_mount_by
self.value = mount_point.mount_by.to_s
end
end
# A group of options that are general for many filesystem types.
class GeneralOptions < CWM::CustomWidget
include FstabCommon
# @macro seeCustomWidget
def contents
return Empty() unless widgets.any?(&:supported_by_filesystem?)
VBox(* widgets.map { |w| to_ui_term(w) }, VSpacing(1))
end
def widgets
[
ReadOnly.new(@controller),
MountUser.new(@controller),
Noauto.new(@controller),
Quota.new(@controller)
]
end
end
# Generic checkbox for fstab options
# VALUES must be a pair: ["fire", "water"] means "fire" is checked and "water" unchecked
class FstabCheckBox < CWM::CheckBox
include FstabCommon
# @macro seeAbstractWidget
def init
self.value = mount_point.mount_options.include?(checked_value)
end
# @macro seeAbstractWidget
def store
delete_fstab_option!(Regexp.union(options))
add_fstab_option(checked_value) if value
end
private
# Possible values
def options
self.class::VALUES
end
def checked_value
self.class::VALUES[0]
end
end
# CheckBox to disable the automount option when starting up
class Noauto < FstabCheckBox
# Possible values of the widget
VALUES = ["noauto", "auto"].freeze
# @macro seeAbstractWidget
def label
_("Do Not Mount at System &Start-up")
end
end
# CheckBox to enable the read only option ("ro")
class ReadOnly < FstabCheckBox
include FstabCommon
# Possible values of the widget
VALUES = ["ro", "rw"].freeze
# @macro seeAbstractWidget
def label
_("Mount &Read-Only")
end
# @macro seeAbstractWidget
def help
_("<p><b>Mount Read-Only:</b>\n" \
"Writing to the file system is not possible. Default is false. During installation\n" \
"the file system is always mounted read-write.</p>")
end
end
# CheckBox to enable the user option which means allow to mount the
# filesystem by an ordinary user
class MountUser < FstabCheckBox
# Possible values of the widget
VALUES = ["user", "nouser"].freeze
# @macro seeAbstractWidget
def label
_("Mountable by User")
end
# @macro seeAbstractWidget
def help
_("<p><b>Mountable by User:</b>\nThe file system may be " \
"mounted by an ordinary user. Default is false.</p>\n")
end
end
# CheckBox to enable the use of user quotas
class Quota < CWM::CheckBox
include FstabCommon
# Possible values of the widget
VALUES = ["grpquota", "usrquota"].freeze
# @macro seeAbstractWidget
def label
_("Enable &Quota Support")
end
# @macro seeAbstractWidget
def help
_("<p><b>Enable Quota Support:</b>\n" \
"The file system is mounted with user quotas enabled.\n" \
"Default is false.</p>")
end
# @macro seeAbstractWidget
def init
self.value = mount_point.mount_options.any? { |o| VALUES.include?(o) }
end
# @macro seeAbstractWidget
def store
delete_fstab_option!(Regexp.union(VALUES))
add_fstab_options("usrquota", "grpquota") if value
end
end
# Generic ComboBox for fstab options.
#
# This uses some constants that each derived class should define:
#
# REGEXP [Regex] The regular expression describing the fstab option.
# If it ends with "=", the value will be appended to it.
#
# ITEMS [Array<String>] The items to choose from.
# The first one is used as the default (initial) value.
#
class FstabComboBox < CWM::ComboBox
include FstabCommon
# Set the combo box value to the current value matching REGEXP.
def init
i = mount_point.mount_options.index { |o| o =~ self.class::REGEXP }
self.value = i ? mount_point.mount_options[i].gsub(self.class::REGEXP, "") : default_value
end
# Convert REGEXP to the option string. This is a very basic
# implementation that just removes a "^" if the regexp contains it.
# For anything more sophisticated, reimplement this.
#
# @return [String]
def option_str
self.class::REGEXP.source.delete("^")
end
# Overriding FstabCommon::supported_by_filesystem? to make use of the
# REGEXP and to avoid having to duplicate it in VALUES
#
# @return [Boolean]
def supported_by_filesystem?
return false if filesystem.nil?
return false unless supported_by_mount_path?
filesystem.type.supported_fstab_options.any? { |opt| opt =~ self.class::REGEXP }
end
# Check if this mount option is supported by the current mount path.
# For /boot/* or the root filesystem some options might not be supported.
#
# @return [Boolean]
def supported_by_mount_path?
true
end
# The default value for the option.
#
# @return [String]
def default_value
items.first.first
end
# Store the current value in the fstab_options.
# If the value is nil or empty, it will only remove the old value.
#
# If option_str (i.e. normally REGEXP) ends with "=", the value is
# appended to it, otherwise only the value is used.
# "codepage=" -> "codepage=value"
# "foo" -> "value"
def store
delete_fstab_option!(self.class::REGEXP)
return if value.nil? || value.empty?
opt = option_str
if opt.end_with?("=")
opt += value
else
opt = value
end
add_fstab_option(opt)
end
# Convert ITEMS to the format expected by the underlying
# CWM::ComboBox.
def items
self.class::ITEMS.map { |val| [val, val] }
end
# Widget options
def opt
[:editable, :hstretch]
end
end
# ComboBox to specify the journal mode to use by the filesystem
class JournalOptions < FstabComboBox
# Format of the option
REGEXP = /^data=/
# @macro seeAbstractWidget
def label
_("Data &Journaling Mode")
end
def default_value
"ordered"
end
def items
[
["journal", _("journal")],
["ordered", _("ordered")],
["writeback", _("writeback")]
]
end
def supported_by_mount_path?
# journal options tend to break remounting root rw (bsc#1077859).
# See also root_fstab_options() in lib/y2storage/filesystems/type.rb
mount_path != "/"
end
# @macro seeAbstractWidget
def help
_("<p><b>Data Journaling Mode:</b>\n" \
"Specifies the journaling mode for file data.\n" \
"<tt>journal</tt> -- All data is committed to the journal prior to being\n" \
"written into the main file system. Highest performance impact.<br>\n" \
"<tt>ordered</tt> -- All data is forced directly out to the main file system\n" \
"prior to its metadata being committed to the journal. Medium performance impact.<br>\n" \
"<tt>writeback</tt> -- Data ordering is not preserved. No performance impact.</p>\n")
end
end
# An input field that allows to set other options that are not handled by
# specific widgets.
#
class ArbitraryOptions < CWM::InputField
include FstabCommon
def initialize(controller, parent_widget)
super(controller) # pass controller to FstabCommon
textdomain "storage"
@controller = controller
@parent_widget = parent_widget
@other_values = nil
@other_regexps = nil
end
# @macro seeCustomWidget
def opt
[:hstretch]
end
# @macro seeAbstractWidget
def label
_("Arbitrary Option &Value")
end
# @macro seeAbstractWidget
def init
self.value = unhandled_options(mount_point.mount_options).join(",")
end
# @macro seeAbstractWidget
def store
keep_only_options_handled_in_other_widgets
return unless value
options = clean_whitespace(value).split(",")
# Intentionally NOT filtering out only unhandled options: When the user
# adds anything here that also has a corresponding checkbox or combo
# box in this same dialog, the value here will win, and when entering
# this dialog again the dedicated widget will take the value from
# there, and it will be filtered out in this arbitrary options widget.
#
# So, when a user insists in adding "noauto,user" here, it is applied
# correctly, but when entering the dialog again, the checkboxes pick up
# those values and they won't show up in this field anymore.
add_fstab_options(*options)
end
# @macro seeAbstractWidget
def help
_(
"<p><b>Arbitrary Option Value:</b> " \
"Enter any other mount options here, separated with commas. " \
"Notice that this does not do any checking, so be careful what you enter here!<br>" \
"If you want to have utf8 encoded filenames with limited case-insensitivity then " \
"add 'utf8' here and leave the Charset for File Names field empty." \
"</p>"
)
end
private
# Clean whitespace. We need to preserve whitespace that might possibly be
# intentional within a mount option, but we want graceful error handling
# when a user put additional blanks between them, e.g. "foo, bar" or
# "foo , bar".
def clean_whitespace(str)
str.gsub(/\s*,\s*/, ",")
end
def keep_only_options_handled_in_other_widgets
mount_point.mount_options = mount_point.mount_options.select do |opt|
handled_in_other_widget?(opt)
end
end
def unhandled_options(options)
options.reject do |opt|
handled_in_other_widget?(opt)
end
end
def handled_in_other_widget?(opt)
return true if other_values.include?(opt)
other_regexps.any? { |r| opt =~ r }
end
# Return all values that are handled by other widgets in this widget tree.
# @return [Array<String>]
def other_values
return [] unless @parent_widget.respond_to?(:values)
@other_values ||= @parent_widget.values
end
# Return all regexps that are handled by other widgets in this widget tree.
# @return [Array<Regexp>]
def other_regexps
return [] unless @parent_widget.respond_to?(:regexps)
@other_regexps ||= @parent_widget.regexps
end
end
# Some options that are mainly specific for one filesystem
class FilesystemsOptions < CWM::CustomWidget
include FstabCommon
# @macro seeCustomWidget
def contents
return Empty() unless widgets.any?(&:supported_by_filesystem?)
VBox(* widgets.map { |w| to_ui_term(w) }, VSpacing(1))
end
def widgets
[
SwapPriority.new(@controller),
TmpfsSize.new(@controller),
IOCharset.new(@controller),
Codepage.new(@controller)
]
end
end
# Swap priority
class SwapPriority < CWM::InputField
include FstabCommon
# Possible values of the widget
VALUES = ["pri="].freeze
# Format of the option
REGEXP = /^pri=/
# Default value of the widget
DEFAULT = "".freeze
# @macro seeAbstractWidget
def label
_("Swap &Priority")
end
# @macro seeAbstractWidget
def store
delete_fstab_option!(REGEXP)
add_fstab_option("pri=#{value}") if value && !value.empty?
end
# @macro seeAbstractWidget
def help
_("<p><b>Swap Priority:</b>\nEnter the swap priority. " \
"Higher numbers mean higher priority.</p>\n")
end
end
# Size for tmpfs
class TmpfsSize < CWM::InputField
include FstabCommon
# Possible values of the widget
VALUES = ["size="].freeze
# Format of the option
REGEXP = /^size=/
# Default value of the widget
DEFAULT = "".freeze
# Regular expression to validate the content of #value
VALUE_REGEXP = /^\d+(k|m|g|%)?$/i
# @macro seeAbstractWidget
def label
_("Max Size")
end
# @macro seeAbstractWidget
def store
delete_fstab_option!(REGEXP)
add_fstab_option("size=#{value}") if value && !value.empty?
end
# @macro seeAbstractWidget
def validate
return true if value.nil? || value.empty?
return true if value =~ VALUE_REGEXP
Yast::Popup.Error(
_(
"The size must be a number,\n" \
"optionally followed by a unit (k, m or g) or by a percent sign (%)."
)
)
focus
false
end
# @macro seeAbstractWidget
def help
_("<p><b>Max Size:</b>\nUpper limit on the size of the file system. " \
"The size is given in bytes by default, optionally followed by a <b>k</b>, <b>m</b> " \
"or <b>g</b> suffix to specify KiB, MiB or GiB. The size may also have a <b>% </b> " \
"suffix to limit this instance to a percentage of physical RAM. " \
"The default, when neither this option nor nr_blocks is specified, is 50%.</p>\n")
end
end
# VFAT IOCharset
class IOCharset < FstabComboBox
# Format of the option
REGEXP = /^iocharset=/
# Possible values
ITEMS = [
"", "iso8859-1", "iso8859-15", "iso8859-2", "iso8859-5", "iso8859-7",
"iso8859-9", "utf8", "koi8-r", "euc-jp", "sjis", "gb2312", "big5",
"euc-kr"
].freeze
# @macro seeAbstractWidget
def store
delete_fstab_option!(/^utf8=.*/)
super
end
def default_value
ITEMS.first
end
def supported_by_mount_path?
return false if mount_path.nil?
# We used to disable the iocharset dialog for filesystems used for booting since
# iocharset=utf8 breaks VFAT case insensitivity (bsc#1080731).
#
# That's taken care of now in {Filesystems::Type#patch_iocharset}
# when we create a new file system.
true
end
# @macro seeAbstractWidget
def label
_("Char&set for File Names")
end
# @macro seeAbstractWidget
def help
_(
"<p><b>Charset for File Names:</b>\n" \
"Set the charset used for display of file names in Windows partitions.<br>\n" \
"Note that choosing 'utf8' here will implicitly make " \
"filename comparison case-sensitve.<br>\n" \
"To avoid this, leave this field empty and instead add 'utf8' " \
"to the Arbitrary Option Value field." \
"</p>\n"
)
end
end
# VFAT Codepage
class Codepage < FstabComboBox
# Format of the option
REGEXP = /^codepage=/
# Possible values
ITEMS = ["", "437", "852", "932", "936", "949", "950"].freeze
def default_value
ITEMS.first
end
# @macro seeAbstractWidget
def label
_("Code&page for Short FAT Names")
end
# @macro seeAbstractWidget
def help
_("<p><b>Codepage for Short FAT Names:</b>\nThis codepage is used for " \
"converting to shortname characters on FAT file systems.</p>\n")
end
end
end
end