Hello community, here is the log from the commit of package yast2-users for openSUSE:Factory checked in at 2019-02-15 09:53:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-users (Old) and /work/SRC/openSUSE:Factory/.yast2-users.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-users" Fri Feb 15 09:53:36 2019 rev:216 rq:674443 version:4.1.7 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-users/yast2-users.changes 2019-01-24 14:00:33.132247320 +0100 +++ /work/SRC/openSUSE:Factory/.yast2-users.new.28833/yast2-users.changes 2019-02-15 09:53:37.591793622 +0100 @@ -1,0 +2,7 @@ +Mon Feb 11 09:38:24 UTC 2019 - [email protected] + +- Allow to create the user home directory as Btrfs subvolume + (fate#316134). +- 4.1.7 + +------------------------------------------------------------------- Old: ---- yast2-users-4.1.6.tar.bz2 New: ---- yast2-users-4.1.7.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-users.spec ++++++ --- /var/tmp/diff_new_pack.z4YFkj/_old 2019-02-15 09:53:38.095793463 +0100 +++ /var/tmp/diff_new_pack.z4YFkj/_new 2019-02-15 09:53:38.099793461 +0100 @@ -12,12 +12,12 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: yast2-users -Version: 4.1.6 +Version: 4.1.7 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ yast2-users-4.1.6.tar.bz2 -> yast2-users-4.1.7.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/package/yast2-users.changes new/yast2-users-4.1.7/package/yast2-users.changes --- old/yast2-users-4.1.6/package/yast2-users.changes 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/package/yast2-users.changes 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Mon Feb 11 09:38:24 UTC 2019 - [email protected] + +- Allow to create the user home directory as Btrfs subvolume + (fate#316134). +- 4.1.7 + +------------------------------------------------------------------- Fri Jan 11 10:05:50 UTC 2019 - [email protected] - Fixed call to renamed method (bsc#1121473). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/package/yast2-users.spec new/yast2-users-4.1.7/package/yast2-users.spec --- old/yast2-users-4.1.6/package/yast2-users.spec 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/package/yast2-users.spec 2019-02-12 10:35:04.000000000 +0100 @@ -17,7 +17,7 @@ Name: yast2-users -Version: 4.1.6 +Version: 4.1.7 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/src/include/users/dialogs.rb new/yast2-users-4.1.7/src/include/users/dialogs.rb --- old/yast2-users-4.1.6/src/include/users/dialogs.rb 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/src/include/users/dialogs.rb 2019-02-12 10:35:04.000000000 +0100 @@ -27,6 +27,7 @@ # # $Id$ +require "pathname" require "shellwords" require "users/ssh_public_key" @@ -389,6 +390,7 @@ create_home = Ops.get_boolean(user, "create_home", true) chown_home = Ops.get_boolean(user, "chown_home", true) no_skel = Ops.get_boolean(user, "no_skeleton", false) + btrfs_subvolume = Ops.get_boolean(user, "btrfs_subvolume", false) do_not_edit = user_type == "nis" complex_layout = installation && Users.StartDialog("user_add") @@ -462,6 +464,7 @@ chown_home = Ops.get_boolean(user, "chown_home", chown_home) no_skel = Ops.get_boolean(user, "no_skeleton", no_skel) + btrfs_subvolume = Ops.get_boolean(user, "btrfs_subvolume", btrfs_subvolume) groups = Ops.get_map(user, "grouplist", {}) do_not_edit = user_type == "nis" @@ -716,28 +719,12 @@ end browse = VBox( - Label(""), - # button label - PushButton(Id(:browse), Opt(:key_F6), _("B&rowse...")), - action != "edited" ? Empty() : Label("") + VSpacing(1), + PushButton(Id(:browse), Opt(:key_F6), _("B&rowse...")) ) home_w = VBox( - # textentry label InputField(Id(:home), Opt(:hstretch), _("&Home Directory"), home), - action != "edited" ? - Empty() : - HBox( - HSpacing(), - Left( - CheckBox( - Id(:move_home), - # check box label - _("&Move to New Location"), - create_home - ) - ) - ) ) new_user_term = action != "added" ? VBox() : @@ -767,7 +754,6 @@ ) ) : VSpacing(0), - VSpacing(0.5), HBox( text_mode ? Empty() : HSpacing(1), HWeight( @@ -784,19 +770,31 @@ ) ), Top( - VBox(HBox(home_w, browse), new_user_term) + VBox( + VSpacing(1), + HBox(home_w, browse), + move_to_new_location_checkbox(action, create_home), + new_user_term, + HBox( + HSpacing(), + Left(CheckBox(Id(:btrfs_subvolume), btrfs_label, btrfs_subvolume)) + ), + ) ), + VSpacing(1), additional_data, + text_mode ? Empty() : HSpacing(1), Top(edit_shell), - Top(edit_defaultgroup), VStretch() ) ), - text_mode ? Empty() : HSpacing(2), + HSpacing(2), HWeight( 2, VBox( VSpacing(0.5), + edit_defaultgroup, + VSpacing(0.5), MultiSelectionBox( Id(:grouplist), # selection box label @@ -815,7 +813,6 @@ ), text_mode ? Empty() : HSpacing(1) ), - VSpacing(0.5) ), HSpacing(1) ) @@ -1011,6 +1008,7 @@ error = "" ret = Convert.to_symbol(UI.UserInput) if current != nil + if (ret == :abort || ret == :cancel) && ReallyAbort() != :abort ret = :notnext next @@ -1328,21 +1326,9 @@ # inside Details dialog if current == :details && ret == :browse - dir = home - if SCR.Read(path(".target.size"), home) == -1 - dir = Users.GetDefaultHome(new_type) - end - dir = UI.AskForExistingDirectory(dir, "") - if dir != nil - if Ops.add(Builtins.findlastof(dir, "/"), 1) == Builtins.size(dir) - dir = Builtins.substring( - dir, - 0, - Ops.subtract(Builtins.size(dir), 1) - ) - end - UI.ChangeWidget(Id(:home), :Value, dir) - end + start_dir = Dir.exists?(home) ? home : Users.GetDefaultHome(new_type) + selected_dir = cleanpath(UI.AskForExistingDirectory(start_dir, "")) + UI.ChangeWidget(Id(:home), :Value, selected_dir) unless selected_dir.empty? end # going from Details dialog @@ -1352,20 +1338,14 @@ new_defaultgroup = Convert.to_string( UI.QueryWidget(Id(:defaultgroup), :Value) ) - new_home = Convert.to_string(UI.QueryWidget(Id(:home), :Value)) + + new_home = cleanpath(UI.QueryWidget(Id(:home), :Value)) if what == "add_user" + btrfs_subvolume = UI.QueryWidget(Id(:btrfs_subvolume), :Value) no_skel = Convert.to_boolean(UI.QueryWidget(Id(:skel), :Value)) mode = Convert.to_string(UI.QueryWidget(Id(:mode), :Value)) end - if Ops.add(Builtins.findlastof(new_home, "/"), 1) == - Builtins.size(new_home) - new_home = Builtins.substring( - new_home, - 0, - Ops.subtract(Builtins.size(new_home), 1) - ) - end if do_not_edit new_home = home @@ -1521,6 +1501,24 @@ create_home = false end + # A flag to decide if the Btrfs path validation should be performed, since it is not + # needed when moving it to other location. The "create_home" above is not reliable because + # it is "true" **when moving the directory/subvolume**. + check_btrfs_path = !UI.QueryWidget(Id(:move_home), :Value) + + # Check if is a valid path when creating a Btfs subvolume + if btrfs_subvolume && check_btrfs_path && !valid_btrfs_path?(new_home) + Report.Error( + # TRANSLATORS: the error message when user try to create a Btrfs subvolume in a not + # valid location + _("Given path is not a valid Btrfs location.\n\n" \ + "Choose another path for the home directory\n" \ + "or uncheck the '%{btrfs_option}' option.") % { btrfs_option: btrfs_label } + ) + focus_tab.call(current, :home) + next + end + home = new_home shell = new_shell uid = new_i_uid @@ -1539,6 +1537,7 @@ Ops.set(user, "addit_data", addit_data) Ops.set(user, "no_skeleton", no_skel) Ops.set(user, "home_mode", mode) + Ops.set(user, "btrfs_subvolume", btrfs_subvolume) end if current == :passwordsettings && (ret == :next || tab) @@ -1752,13 +1751,18 @@ UI.ReplaceWidget(:tabContents, get_details_term.call) Wizard.SetHelpText(EditUserDetailsDialogHelp(user_type, what)) + UI.ChangeWidget(Id(:btrfs_subvolume), :Enabled, btrfs_available?) + + if what == "edit_user" + UI.ChangeWidget(Id(:btrfs_subvolume), :Enabled, false) + # Show the value for the current home directory/subvolume + UI.ChangeWidget(Id(:btrfs_subvolume), :Value, btrfs_subvolume?(org_home)) + end + if do_not_edit - UI.ChangeWidget(Id(:uid), :Enabled, false) - UI.ChangeWidget(Id(:home), :Enabled, false) - UI.ChangeWidget(Id(:move_home), :Enabled, false) - UI.ChangeWidget(Id(:shell), :Enabled, false) - UI.ChangeWidget(Id(:defaultgroup), :Enabled, false) - UI.ChangeWidget(Id(:browse), :Enabled, false) + [:uid, :home, :move_home, :shell, :defaultgroup, :browse, :btrfs_subvolume].each do |widget| + UI.ChangeWidget(Id(widget), :Enabled, false) + end end if user_type == "ldap" && !Ldap.file_server UI.ChangeWidget(Id(:browse), :Enabled, false) @@ -1869,6 +1873,73 @@ ret end + def move_to_new_location_checkbox(action, checked) + return Empty() if action != "edited" + + HBox( + HSpacing(), + Left( + CheckBox(Id(:move_home), _("&Move to New Location"), checked) + ) + ) + end + + def btrfs_label + # TRANSLATORS: label for the checkbox that allows to create the user home directory as a + # Btrfs subvolume + _("Create as Btrfs Subvolume") + end + + # Returns clean path + # + # Also useful to remove the trailing backslash + # + # @param [String] path + # + # @return [String] a string path representation or empty string + def cleanpath(path) + return "" if path.nil? || path.empty? + + Pathname.new(path).cleanpath.to_s + rescue TypeError + "" + end + + # Check if given path is in a btrfs filesystem + # + # @param [String, Pathname] path + # + # @return [Boolean] true when is a path in a Btrfs filesystem; false otherwise + def valid_btrfs_path?(path) + dirname = Pathname.new(path).dirname + fstype = Yast::Execute.locally!.stdout("/usr/bin/stat", "-f", "--format", "%T", dirname).chomp + + fstype == "btrfs" + end + + # Whether there is a Btrfs filesystem present + # + # @return [Boolean] true if a Btrfs filesystem is found; false otherwise + def btrfs_available? + available_filesystems = Yast::Execute.locally!.stdout( + ["/usr/bin/df", "--output=fstype"], + ["/usr/bin/tail", "-n", "+2"] + ).split("\n") + + available_filesystems.include?("btrfs") + end + + # Whether given path is a Btrfs subvolume + # + # @param [String, Pathname] path + # + # @return [Boolean] true when is a Btrfs subvolume; false otherwise + def btrfs_subvolume?(path) + return false if path.to_s.empty? + + !Yast::Execute.locally!.stdout("/usr/sbin/btrfs", "subvolume", "show", path).empty? + end + # Dialog for adding/editing group # @param [String] what "add_group" or "edit_group" # @return [Symbol] for wizard sequencer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/src/include/users/helps.rb new/yast2-users-4.1.7/src/include/users/helps.rb --- old/yast2-users-4.1.6/src/include/users/helps.rb 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/src/include/users/helps.rb 2019-02-12 10:35:04.000000000 +0100 @@ -381,135 +381,117 @@ # Help for EditUserDetailsDialog. - # @param [String] user_type type of edited user (local/system/ldap/nis) + # + # @param [String] user_type type of added/edited user (local/system/ldap/nis) # @param [String] what what to do with a user (add_user/edit_user) + # # @return [String] help text def EditUserDetailsDialogHelp(user_type, what) - # help text 1/8 - helptext = Ops.add( - Ops.add( - Ops.add( - _("<p>\nAdditional user data includes:\n</p>"), - # help text 2/8, %1 is number - Builtins.sformat( - _( - "<p>\n" + - "<b>User ID (uid):</b>\n" + - "Each user is known to the system by a unique number,\n" + - "the user ID. For normal users, you should use\n" + - "a UID larger than %1 because the smaller UIDs are used\n" + - "by the system for special purposes and pseudo logins.\n" + - "</p>\n" - ), - UsersCache.GetMaxUID("system") - ) - ), - # help text 3/8 - _( - "<p>\n" + - "If you change the UID of an existing user, the rights of the files\n" + - "this user owns must be changed. This is done automatically\n" + - "for the files in the user's home directory, but not for files \n" + - "located elsewhere.</p>\n" - ) - ), - # help text 4/8 + helptext = "" + + helptext << _("<p>\nAdditional user data includes:\n</p>") + # TRANSLATORS: %1 is a number + helptext << Builtins.sformat( _( - "<p>\n" + - "<b>Home Directory:</b>\n" + - "The home directory of the user. Normally this is\n" + - "/home/username. \n" + - "To select an existing directory, click <b>Browse</b>.\n" + - "</p>\n" - ) + "<p>\n" \ + "<b>User ID (uid):</b>\n" \ + "Each user is known to the system by a unique number,\n" \ + "the user ID. For normal users, you should use\n" \ + "a UID larger than %1 because the smaller UIDs are used\n" \ + "by the system for special purposes and pseudo logins.\n" \ + "</p>\n" + ), + UsersCache.GetMaxUID("system") ) + helptext << _( + "<p>\n" \ + "If you change the UID of an existing user, the rights of the files\n" \ + "this user owns must be changed. This is done automatically\n" \ + "for the files in the user's home directory, but not for files \n" \ + "located elsewhere.</p>\n" + ) + helptext << _( + "<p>\n" \ + "<b>Home Directory:</b>\n" \ + "The home directory of the user. Normally this is\n" \ + "/home/username. \n" \ + "To select an existing directory, click <b>Browse</b>.\n" \ + "</p>\n" + ) + if what == "add_user" # help text for user's home directory mode - helptext = Ops.add( - helptext, - _( - "<p>Optionally, set the <b>Home Directory Permission Mode</b> for this user's home directory different from the default.</p>" - ) + helptext << _( + "<p>Optionally, set the <b>Home Directory Permission Mode</b> " \ + "for this user's home directory different from the default.</p>" ) - defaults = Users.GetLoginDefaults - helptext = Ops.add( - helptext, - # alternate helptext 4.5/8; %1 is directory (e.g. '/etc/skel') - Builtins.sformat( - _( - "<p>To create only an empty home directory,\n" + - "check <b>Empty Home</b>. Otherwise, the new home directory\n" + - "is created from the default skeleton (%1).</p>\n" - ), - Ops.get_string(defaults, "skel", "") - ) + # help text for an empty home option + # TRANSLATORS: %1 is a path to directory (e.g. '/etc/skel') + helptext << Builtins.sformat( + _( + "<p>To create only an empty home directory,\n" \ + "check <b>Empty Home</b>. Otherwise, the new home directory\n" \ + "is created from the default skeleton (%1).</p>\n" + ), + Users.GetLoginDefaults.fetch("skel", "") ) + + btrfs_option_label = _("Create as Btrfs Subvolume") + # TRANSLATORS: help text for the Btrfs subvolume checkbox + helptext << _( + "<p><b>%s</b> option allows to create the user home " \ + "as a subvolume instead of a plain directory whenever " \ + "there is a Btrfs filesystem available.</p>" + ) % btrfs_option_label else # help text for Move to new location checkbox - helptext = Ops.add( - helptext, - _( - "<p>If changing the location of a user's home directory, move the contents of the current directory with <b>Move to New Location</b>, activated by default. Otherwise a new home directory is created without any of the existing data.</p>" - ) + helptext << _( + "<p>If changing the location of a user's home directory, move the contents " \ + "of the current directory with <b>Move to New Location</b>, activated by default. " \ + "Otherwise a new home directory is created without any of the existing data.</p>" ) end if user_type == "ldap" - helptext = Ops.add( - helptext, - # alternate helptext 5/8 - _( - "<p>\n" + - "The home directory of an LDAP user can be changed only on the\n" + - "file server.</p>" - ) + helptext << _( + "<p>\n" \ + "The home directory of an LDAP user can be changed only on the\n" \ + "file server.</p>" ) elsif user_type == "system" || user_type == "local" - helptext = Ops.add( - helptext, - # alternate helptext 5/8 - _( - "<p><b>Additional Information:</b>\n" + - "Some additional user data could be set here. This field may contain up to\n" + - "three parts, separated by commas. The standard usage is to write\n" + - "<i>office</i>,<i>work phone</i>,<i>home phone</i>. This information is \n" + - "shown when you use the <i>finger</i> command on this user.</p>\n" - ) + helptext << _( + "<p><b>Additional Information:</b>\n" \ + "Some additional user data could be set here. This field may contain up to\n" \ + "three parts, separated by commas. The standard usage is to write\n" \ + "<i>office</i>,<i>work phone</i>,<i>home phone</i>. This information is \n" \ + "shown when you use the <i>finger</i> command on this user.</p>\n" ) end - # help text 6/8 - helptext = Ops.add( - Ops.add( - Ops.add( - helptext, - _( - "<p>\n" + - "<b>Login Shell:</b>\n" + - "The login shell (command interpreter) for the user.\n" + - "Select a shell from the list of all shells installed\n" + - "on your system.\n" + - "</p>" - ) - ), - # help text 7/8 - _( - "<p>\n" + - "<b>Default Group:</b>\n" + - "The primary group to which the user belongs. Select one group\n" + - "from the list of all groups existing on your system.\n" + - "</p>" - ) - ), - # help text 8/8 - _( - "<p>\n" + - "<b>Additional Groups:</b>\n" + - "Select additional groups in which the user should be a member.\n" + - "</p>\n" - ) + helptext << _( + "<p>\n" \ + "<b>Login Shell:</b>\n" \ + "The login shell (command interpreter) for the user.\n" \ + "Select a shell from the list of all shells installed\n" \ + "on your system.\n" \ + "</p>" + ) + + helptext << _( + "<p>\n" \ + "<b>Default Group:</b>\n" \ + "The primary group to which the user belongs. Select one group\n" \ + "from the list of all groups existing on your system.\n" \ + "</p>" + ) + helptext << _( + "<p>\n" \ + "<b>Additional Groups:</b>\n" \ + "Select additional groups in which the user should be a member.\n" \ + "</p>\n" ) + helptext end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/src/modules/Users.pm new/yast2-users-4.1.7/src/modules/Users.pm --- old/yast2-users-4.1.6/src/modules/Users.pm 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/src/modules/Users.pm 2019-02-12 10:35:04.000000000 +0100 @@ -117,6 +117,7 @@ "expire" => "", "shell" => "", "skel" => "", + "btrfs_subvolume" => 0, "groups" => "", "umask" => "022" ); @@ -3029,25 +3030,33 @@ # ---------------------------------------------------------------- # now copy the data to map of current user - foreach my $key (keys %data) { - if ($key eq "create_home" || $key eq "encrypted" || - $key eq "chown_home" || - $key eq "delete_home" || $key eq "no_skeleton" || - $key eq "disabled" || $key eq "enabled") { - $user_in_work{$key} = YaST::YCP::Boolean ($data{$key}); - } - elsif ($key eq "userPassword" && (defined $data{$key}) && - # crypt password only once - !bool ($data{"encrypted"})) - { - $user_in_work{$key} = $self->CryptPassword ($data{$key}, $type); - $user_in_work{"encrypted"} = YaST::YCP::Boolean (1); - $user_in_work{"text_userpassword"} = $data{$key}; - } - else { - $user_in_work{$key} = $data{$key}; - } + foreach my $key ( keys %data ) { + if ( $key eq "create_home" + || $key eq "encrypted" + || $key eq "chown_home" + || $key eq "delete_home" + || $key eq "no_skeleton" + || $key eq "btrfs_subvolume" + || $key eq "disabled" + || $key eq "enabled" ) + { + $user_in_work{$key} = YaST::YCP::Boolean( $data{$key} ); + } + elsif ( + $key eq "userPassword" + && ( defined $data{$key} ) + && !bool( $data{"encrypted"} ) # crypt password only once + ) + { + $user_in_work{$key} = $self->CryptPassword( $data{$key}, $type ); + $user_in_work{"encrypted"} = YaST::YCP::Boolean(1); + $user_in_work{"text_userpassword"} = $data{$key}; + } + else { + $user_in_work{$key} = $data{$key}; + } } + $user_in_work{"type"} = $type; $user_in_work{"what"} = "add_user"; @@ -4463,9 +4472,10 @@ next; #rest of work with homes for LDAP are ruled in WriteLDAP } foreach my $username (keys %{$modified_users{$type}}) { - + my %user = %{$modified_users{$type}{$username}}; my $home = $user{"homeDirectory"} || ""; + my $use_btrfs_subvolume = $user{"btrfs_subvolume"} || 0; my $uid = $user{"uidNumber"} || 0; my $command = ""; my $user_mod = $user{"modified"} || "no"; @@ -4474,6 +4484,7 @@ my $chown_home = $user{"chown_home"}; $chown_home = 1 if (!defined $chown_home); my $skel = $useradd_defaults{"skel"}; + if ($user_mod eq "imported" || $user_mod eq "added") { y2usernote ("User '$username' created"); @@ -4488,7 +4499,7 @@ if ((bool ($create_home) || $user_mod eq "imported") && !%{SCR->Read (".target.stat", $home)}) { - UsersRoutines->CreateHome ($skel, $home); + UsersRoutines->CreateHome ($skel, $home, $use_btrfs_subvolume); } if ($home ne "/var/lib/nobody" && bool ($chown_home)) { if (UsersRoutines->ChownHome ($uid, $gid, $home)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/src/modules/UsersRoutines.pm new/yast2-users-4.1.7/src/modules/UsersRoutines.pm --- old/yast2-users-4.1.6/src/modules/UsersRoutines.pm 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/src/modules/UsersRoutines.pm 2019-02-12 10:35:04.000000000 +0100 @@ -23,16 +23,16 @@ # UsersRoutines module # - package UsersRoutines; use strict; +use File::Basename; use YaST::YCP qw(:LOGGING); our %TYPEINFO; - + ##------------------------------------ ##------------------- global imports @@ -63,9 +63,19 @@ # could we use pam_mount? currntly not if fingerprint dev is in use (bnc#390810) my $crypted_homes_enabled = undef; +# path to btrfs +my $btrfs = "/usr/sbin/btrfs"; + ##------------------------------------------------------------------------- ##----------------- helper routines --------------------------------------- +sub btrfs_subvolume { + my $path = shift; + my $cmd = "$btrfs subvolume show $path"; + + return ( SCR->Execute( ".target.bash", $cmd ) eq 0 ); +} + ##------------------------------------------------------------------------- ##----------------- directory manipulation routines ----------------------- @@ -73,6 +83,7 @@ # Create home directory # @param skeleton skeleton directory for new home # @param home name of new home directory +# @param use_btrfs whether the home directory must be a btrfs subvolume # @return success BEGIN { $TYPEINFO{CreateHome} = ["function", "boolean", @@ -80,41 +91,65 @@ } sub CreateHome { - my $self = shift; - my $skel = $_[0]; - my $home = $_[1]; + my $self = shift; + my ( $skel, $home, $use_btrfs ) = @_; - # create a path to new home directory, if not exists - my $home_path = substr ($home, 0, rindex ($home, "/")); - if (length($home_path) and !%{SCR->Read (".target.stat", $home_path)}) { - SCR->Execute (".target.mkdir", $home_path); + # Create a path to new home directory, if not exists + my $home_path = substr( $home, 0, rindex( $home, "/" ) ); + if ( length($home_path) and !%{ SCR->Read( ".target.stat", $home_path ) } ) + { + SCR->Execute( ".target.mkdir", $home_path ); } - my %stat = %{SCR->Read (".target.stat", $home)}; + + my %stat = %{ SCR->Read( ".target.stat", $home ) }; if (%stat) { - if ($home ne "/var/lib/nobody") { - y2error ("$home directory already exists: no mkdir"); - } - return 0; - } + if ( $home ne "/var/lib/nobody" ) { + y2error("$home directory already exists: no mkdir"); + } + return 0; + } + + # Create the home as btrfs subvolume + if ($use_btrfs) { + my $cmd = "btrfs subvolume create $home"; + my %cmd_out = %{ SCR->Execute( ".target.bash_output", $cmd ) }; + my $stderr = $cmd_out{"stderr"} || ""; + if ($stderr) + { + y2error("Error creating '$home' as btrfs subvolume: $stderr"); - # if skeleton does not exist, do not copy it - if ($skel eq "" || !%{SCR->Read (".target.stat", $skel)}) { - if (! SCR->Execute (".target.mkdir", $home)) { - y2error ("error creating $home"); - return 0; - } + return 0; + } } - # now copy homedir from skeleton + # or as a plain directory else { - my $command = "/usr/bin/cp -r '".String->Quote($skel)."' '".String->Quote($home)."'"; - my %out = %{SCR->Execute (".target.bash_output", $command)}; - if (($out{"stderr"} || "") ne "") { - y2error ("error calling $command: ", $out{"stderr"} || ""); - return 0; - } - y2usernote ("Home directory created: '$command'."); + if ( !SCR->Execute( ".target.mkdir", $home ) ) { + y2error("Error creating '$home'"); + + return 0; + } } - y2milestone ("The directory $home was successfully created."); + + # Now copy the skeleton + if ( $skel ne "" && %{ SCR->Read( ".target.stat", $skel ) } ) { + my $cmd = sprintf( + "/usr/bin/cp -r '%s/.' '%s'", + String->Quote($skel), + String->Quote($home) + ); + my %cmd_out = %{ SCR->Execute( ".target.bash_output", $cmd ) }; + my $stderr = $cmd_out{"stderr"} || ""; + + if ( $stderr ne "" ) { + y2error( "Error calling $cmd: $stderr" ); + return 0; + } + + y2usernote("Home skeleton copied: '$cmd'."); + } + + y2milestone("The directory $home was successfully created."); + return 1; } @@ -242,22 +277,39 @@ BEGIN { $TYPEINFO{DeleteHome} = ["function", "boolean", "string"];} sub DeleteHome { - my $self = shift; - my $home = $_[0]; + my $self = shift; + my $home = $_[0]; + my %stat = %{ SCR->Read( ".target.stat", $home ) }; - my %stat = %{SCR->Read (".target.stat", $home)}; - if (!%stat || !($stat{"isdir"} || 0)) { - y2warning("home directory does not exist or is not a directory: no rm"); - return 1; + if ( !%stat || !( $stat{"isdir"} || 0 ) ) { + y2warning("home directory '$home' does not exist or is not a directory: no rm"); + return 1; } - my $command = "/usr/bin/rm -rf '".String->Quote($home)."'"; - my %out = %{SCR->Execute (".target.bash_output", $command)}; - if (($out{"stderr"} || "") ne "") { - y2error ("error calling $command: ", $out{"stderr"} || ""); - return 0; + + my $cmd; + my $type; + + if ( btrfs_subvolume($home) ) { + $cmd = sprintf( "$btrfs subvolume delete -C '%s'", String->Quote($home) ); + $type = "btrfs subvolume"; + } + else { + $cmd = sprintf( "/usr/bin/rm -rf '%s'", String->Quote($home) ); + $type = "directory"; } - y2milestone ("The directory $home was succesfully deleted"); - y2usernote ("Home directory removed: '$command'"); + + my %cmd_output = %{ SCR->Execute( ".target.bash_output", $cmd ) }; + my $stderr = $cmd_output{"stderr"} || ""; + + if ( $stderr ne "" ) { + y2error( "Error calling '$cmd': $stderr" ); + + return 0; + } + + y2milestone("The $type '$home' was succesfully deleted"); + y2usernote("Home $type removed: '$cmd'"); + return 1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/test/dialogs_test.rb new/yast2-users-4.1.7/test/dialogs_test.rb --- old/yast2-users-4.1.6/test/dialogs_test.rb 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/test/dialogs_test.rb 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,7 @@ require_relative "./test_helper" + +require "yast2/execute"; + Yast.import "UI" class UsersDialogsDummy < Yast::Module @@ -16,6 +19,127 @@ allow(Yast).to receive(:import).with("LdapPopup") end + describe "#cleanpath" do + it "returns sanitized path" do + expect(subject.cleanpath("/home/user/")).to eq("/home/user") + end + + context "when nil value is given" do + it "returns empty string" do + expect(subject.cleanpath(nil)).to eq("") + end + end + + context "when empty string is given" do + it "returns empty string" do + expect(subject.cleanpath(nil)).to eq("") + end + end + + context "when something is wrong" do + before do + allow(Pathname).to receive(:new).and_raise + end + + it "returns empty string" do + expect(subject.cleanpath(nil)).to eq("") + end + end + end + + describe "#valid_btrfs_path?" do + let(:local_execution) { double } + let(:dirname) { "/home" } + let(:user_home) { "#{dirname}/user" } + let(:user_home_pathname) { double("Pathname", dirname: dirname) } + + before do + allow(Pathname).to receive(:new).with(user_home).and_return(user_home_pathname) + allow(Yast::Execute).to receive(:locally!).and_return(local_execution) + allow(local_execution).to receive(:stdout) + .with("/usr/bin/stat", any_args, dirname) + .and_return(filesystem) + end + + context "when given path is on Btrfs filesystem" do + let(:filesystem) { "btrfs\n" } + + it "returns true" do + expect(subject.valid_btrfs_path?(user_home)).to eq(true) + end + end + + context "when given path is not on Btrfs filesystem" do + let(:filesystem) { "nfs\n" } + + it "returns false" do + expect(subject.valid_btrfs_path?(user_home)).to eq(false) + end + end + end + + describe "#btrfs_available?" do + let(:local_execution) { double } + + before do + allow(Yast::Execute).to receive(:locally!).and_return(local_execution) + allow(local_execution).to receive(:stdout) + .with(array_including("/usr/bin/df"), any_args) + .and_return(available_filesystems) + end + + context "when there is a Btrfs filesystem" do + let(:available_filesystems) { "ext4\nbtrfs" } + + it "returns true" do + expect(subject.btrfs_available?).to eq(true) + end + end + + context "when there is not a Btrfs filesystem" do + let(:available_filesystems) { "ext4\nnfs" } + + it "returns false" do + expect(subject.btrfs_available?).to eq(false) + end + end + end + + describe "#btrfs_subvolume?" do + let(:local_execution) { double } + let(:subvolume_info) { "" } + let(:path) { "/fake/path/to/user/home" } + + before do + allow(Yast::Execute).to receive(:locally!).and_return(local_execution) + allow(local_execution).to receive(:stdout) + .with("/usr/sbin/btrfs", "subvolume", "show", path) + .and_return(subvolume_info) + end + + context "when path is empty" do + let(:path) { Pathname.new("") } + + it "returns false" do + expect(subject.btrfs_subvolume?(path)).to eq(false) + end + end + + context "when given path is a Btrfs subvolume" do + let(:subvolume_info) { "@/fake/path/to/user/home\n..." } + + it "returns true" do + expect(subject.btrfs_subvolume?(path)).to eq(true) + end + end + + context "when given path is not a Btrfs subvolume" do + it "returns false" do + expect(subject.btrfs_subvolume?(path)).to eq(false) + end + end + end + describe "#ask_chown_home" do before(:each) do expect(Yast::UI).to receive(:OpenDialog) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/AddGroup.out new/yast2-users-4.1.7/testsuite/tests/AddGroup.out --- old/yast2-users-4.1.6/testsuite/tests/AddGroup.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/AddGroup.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,5 @@ Dump ========================================================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/AddUser.out new/yast2-users-4.1.7/testsuite/tests/AddUser.out --- old/yast2-users-4.1.6/testsuite/tests/AddUser.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/AddUser.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,5 @@ Dump ========================================================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/BuildAdditional.out new/yast2-users-4.1.7/testsuite/tests/BuildAdditional.out --- old/yast2-users-4.1.6/testsuite/tests/BuildAdditional.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/BuildAdditional.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,5 @@ Dump ========================================================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/DeleteUser.out new/yast2-users-4.1.7/testsuite/tests/DeleteUser.out --- old/yast2-users-4.1.6/testsuite/tests/DeleteUser.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/DeleteUser.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,3 +1,4 @@ +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/DeleteUserCryptedDir.out new/yast2-users-4.1.7/testsuite/tests/DeleteUserCryptedDir.out --- old/yast2-users-4.1.6/testsuite/tests/DeleteUserCryptedDir.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/DeleteUserCryptedDir.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,3 +1,4 @@ +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" @@ -33,6 +34,7 @@ Write .target.string "/etc/shadow" "at:!:13636:0:99999:7:::\nbin:*:13636::::::\ndaemon:*:13636::::::\nmail:*:13636::::::\nnobody:*:13636::::::\nroot:password:13636::::::\nuucp:*:13636::::::\n+::0:0:0::::\n" true Execute .target.bash "/usr/sbin/nscd -i passwd" 0 Read .target.stat "/home/hh" $["isdir":true] -Execute .target.bash_output "/usr/bin/rm -rf '/home/hh'" $["exit":0] +Execute .target.bash "/usr/sbin/btrfs subvolume show /home/hh" 0 +Execute .target.bash_output "/usr/sbin/btrfs subvolume delete -C '/home/hh'" $["exit":0] Write .target.ycp "/var/lib/YaST2/users.ycp" $["custom_groups":["local"], "custom_users":["local"], "dont_warn_when_nisserver_notdes":false, "dont_warn_when_uppercase":false] true Return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/EditUser.out new/yast2-users-4.1.7/testsuite/tests/EditUser.out --- old/yast2-users-4.1.6/testsuite/tests/EditUser.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/EditUser.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,5 @@ Dump ========================================================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/EditUsersGroups.out new/yast2-users-4.1.7/testsuite/tests/EditUsersGroups.out --- old/yast2-users-4.1.6/testsuite/tests/EditUsersGroups.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/EditUsersGroups.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,3 +1,4 @@ +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/Import.out new/yast2-users-4.1.7/testsuite/tests/Import.out --- old/yast2-users-4.1.6/testsuite/tests/Import.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/Import.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump local user names: Dump [] +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/Read.out new/yast2-users-4.1.7/testsuite/tests/Read.out --- old/yast2-users-4.1.6/testsuite/tests/Read.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/Read.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,5 @@ Dump ========================================================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 0 Read .etc.default.useradd."groups" 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/SelectUser.out new/yast2-users-4.1.7/testsuite/tests/SelectUser.out --- old/yast2-users-4.1.6/testsuite/tests/SelectUser.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/SelectUser.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,4 +1,5 @@ Dump ========================================================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupAdd.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupAdd.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupAdd.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupAdd.out 2019-02-12 10:35:04.000000000 +0100 @@ -2,6 +2,7 @@ Return nil Return nil Dump ============ add new group 'gg': ========================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" @@ -23,6 +24,7 @@ Return Dump ============ add new group 'gg' - done ==================== Dump ============ add new group 'gg2' with first userlist as list == +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" @@ -44,6 +46,7 @@ Return Dump ============ add new group 'gg2' - done ==================== Dump ============ add new group 'gg3' with first userlist as map == +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" @@ -65,6 +68,7 @@ Return Dump ============ add new group 'gg3' - done ==================== Dump ============ add new group 'gg4' with non existent user == +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" @@ -81,6 +85,7 @@ Return User hh2 does not exist. Dump ============ add new group 'gg4' - done ==================== Dump ============ add new group 'root' (groupname conflict): ====== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" nil Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupDelete.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupDelete.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupDelete.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupDelete.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ delete non-existent group: ================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupGet.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupGet.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupGet.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupGet.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ get group 'us': ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupMemberAdd.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupMemberAdd.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupMemberAdd.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupMemberAdd.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ================ (add user) ======================= +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupMemberDelete.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupMemberDelete.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupMemberDelete.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupMemberDelete.out 2019-02-12 10:35:04.000000000 +0100 @@ -3,6 +3,7 @@ Return No user was specified. Dump ================ done ============================ Dump ================ (bad user) ====================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupModify.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupModify.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupModify.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupModify.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ edit non-existing group 'gg': ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupsGet.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupsGet.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupsGet.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupsGet.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ get local groups ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIGroupsGetByUser.out new/yast2-users-4.1.7/testsuite/tests/YaPIGroupsGetByUser.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIGroupsGetByUser.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIGroupsGetByUser.out 2019-02-12 10:35:04.000000000 +0100 @@ -3,6 +3,7 @@ Return $[] Dump ============ get done ============================ Dump ============ get groups (wrong user) =================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUserAdd.out new/yast2-users-4.1.7/testsuite/tests/YaPIUserAdd.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUserAdd.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUserAdd.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ add new user 'jj': ========================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUserDelete.out new/yast2-users-4.1.7/testsuite/tests/YaPIUserDelete.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUserDelete.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUserDelete.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ delete non-existent user: ================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUserDisable.out new/yast2-users-4.1.7/testsuite/tests/YaPIUserDisable.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUserDisable.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUserDisable.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,6 +1,7 @@ Dump ========================================================== Return nil Dump ============ disable LDAP user 'jj': ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUserEnable.out new/yast2-users-4.1.7/testsuite/tests/YaPIUserEnable.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUserEnable.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUserEnable.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ enable local user 'hh': ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUserFeatureAdd.out new/yast2-users-4.1.7/testsuite/tests/YaPIUserFeatureAdd.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUserFeatureAdd.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUserFeatureAdd.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ edit user 'hh': ================================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUserGet.out new/yast2-users-4.1.7/testsuite/tests/YaPIUserGet.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUserGet.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUserGet.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ get local user 'hh': ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUserModify.out new/yast2-users-4.1.7/testsuite/tests/YaPIUserModify.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUserModify.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUserModify.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ edit non-existing user 'jj': ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-4.1.6/testsuite/tests/YaPIUsersGet.out new/yast2-users-4.1.7/testsuite/tests/YaPIUsersGet.out --- old/yast2-users-4.1.6/testsuite/tests/YaPIUsersGet.out 2019-01-11 12:40:30.000000000 +0100 +++ new/yast2-users-4.1.7/testsuite/tests/YaPIUsersGet.out 2019-02-12 10:35:04.000000000 +0100 @@ -1,5 +1,6 @@ Dump ========================================================== Dump ============ get local users ===================== +Read .etc.default.useradd."btrfs_subvolume" 0 Read .etc.default.useradd."expire" 0 Read .etc.default.useradd."group" 100 Read .etc.default.useradd."groups" "audio,video"
