Setup-File
view release on metacpan or search on metacpan
lib/Setup/File.pm view on Meta::CPAN
Unfixable state: `path` doesn't exist.
_
args => {
path => {
summary => 'Path to file/directory',
schema => 'str*',
req => 1,
pos => 0,
},
owner => {
summary => 'Numeric UID or username',
schema => 'str*',
},
group => {
summary => 'Numeric GID or group',
schema => 'str*',
},
follow_symlink => {
summary => 'Whether to follow symlink',
schema => [bool => {default=>0}],
},
orig_owner => {
summary=>'If set, confirm if current owner is not the same as this',
schema => 'str',
},
orig_group => {
summary=>'If set, confirm if current group is not the same as this',
schema => 'str',
},
},
features => {
tx => {v=>2},
idempotent => 1,
},
};
sub chown {
require Lchown;
return [412, "lchown() is not available on this system"] unless
Lchown::LCHOWN_AVAILABLE();
my %args = @_;
# TMP, schema
my $tx_action = $args{-tx_action} // '';
my $dry_run = $args{-dry_run};
my $path = $args{path};
defined($path) or return [400, "Please specify path"];
my $follow_sym = $args{follow_symlink} // 0;
my $orig_owner = $args{orig_owner};
my $orig_group = $args{orig_group};
my $want_owner = $args{owner};
my $want_group = $args{group};
defined($want_owner) || defined($want_group)
or return [400, "Please specify at least either owner/group"];
my ($orig_uid, $orig_uname);
if (defined $orig_owner) {
if ($orig_owner =~ /\A\d+\z/) {
$orig_uid = $orig_owner;
my @ent = getpwuid($orig_uid);
$orig_uname = $ent[0] if @ent;
} else {
$orig_uname = $orig_owner;
my @ent = getpwnam($orig_uname);
return [412, "User doesn't exist: $orig_uname"] unless @ent;
$orig_uid = $ent[2];
}
}
my ($want_uid, $want_uname);
if (defined $want_owner) {
if ($want_owner =~ /\A\d+\z/) {
$want_uid = $want_owner;
my @ent = getpwuid($want_uid);
$want_uname = $ent[0] if @ent;
} else {
$want_uname = $want_owner;
my @ent = getpwnam($want_uname);
return [412, "User doesn't exist: $want_uname"] unless @ent;
$want_uid = $ent[2];
}
}
my ($orig_gid, $orig_gname);
if (defined $orig_group) {
if ($orig_group =~ /\A\d+\z/) {
$orig_gid = $orig_group;
my @grent = getgrgid($orig_gid);
$orig_gname = $grent[0] if @grent;
} else {
$orig_gname = $orig_group;
my @grent = getgrnam($orig_gname);
return [412, "Group doesn't exist: $orig_gname"] unless @grent;
$orig_gid = $grent[2];
}
}
my ($want_gid, $want_gname);
if (defined $want_group) {
if ($want_group =~ /\A\d+\z/) {
$want_gid = $want_group;
my @grent = getgrgid($want_gid);
$want_gname = $grent[0] if @grent;
} else {
$want_gname = $want_group;
my @grent = getgrnam($want_gname);
return [412, "Group doesn't exist: $want_gname"] unless @grent;
$want_gid = $grent[2];
}
}
my @st = lstat($path);
my $is_sym = (-l _);
my $exists = $is_sym || (-e _);
if ($follow_sym && $exists) {
@st = stat($path);
return [500, "Can't stat $path (2): $!"] unless @st;
}
my $cur_uid = $st[4];
my $cur_gid = $st[5];
if (!$args{-tx_recovery} && !$args{-confirm}) {
my $changed = defined($orig_uid) && $orig_uid != $cur_uid ||
defined($orig_gid) && $orig_gid != $cur_gid;
return [331, "File $path has changed ownership, confirm chown?"]
if $changed;
}
#$log->tracef("path=%s, cur_uid=%s, cur_gid=%s, want_uid=%s, want_uname=%s, want_gid=%s, want_gname=%s", $cur_uid, $cur_gid, $want_uid, $want_uname, $want_gid, $want_gname);
if ($tx_action eq 'check_state') {
my @undo;
return [412, "$path doesn't exist"] if !$exists;
if (defined($want_uid) && $cur_uid != $want_uid ||
defined($want_gid) && $cur_gid != $want_gid) {
log_info("(DRY) Chown %s to (%s, %s)",
( run in 1.811 second using v1.01-cache-2.11-cpan-e1769b4cff6 )