Add remote directory init on WHM remote creation

When adding a remote via WHM, create the base directory structure
on the remote server (matching gniza init remote CLI behavior).
Creates $REMOTE_BASE/<hostname>/accounts/ via SSH mkdir or rclone mkdir.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-04 03:41:40 +02:00
parent 66870d9604
commit 84b2f464c9
2 changed files with 87 additions and 0 deletions

View File

@@ -463,6 +463,68 @@ sub test_rclone_connection {
return (0, $msg);
}
# ── Remote Init (create base directory) ──────────────────────
sub init_remote_dir {
my (%args) = @_;
my $type = $args{type} // 'ssh';
my $base = $args{remote_base} // '/backups';
chomp(my $hostname = `hostname -f 2>/dev/null` || `hostname`);
my $remote_path = "$base/$hostname/accounts";
if ($type eq 'ssh') {
my @ssh_args = (
'ssh', '-n',
'-p', ($args{port} || '22'),
'-o', 'StrictHostKeyChecking=accept-new',
'-o', 'ConnectTimeout=10',
'-o', 'BatchMode=yes',
);
if (($args{auth_method} // 'key') eq 'password') {
push @ssh_args, "$args{user}\@$args{host}", "mkdir -p '$remote_path'";
my @cmd = ('sshpass', '-p', $args{password}, @ssh_args);
system(@cmd);
} else {
push @ssh_args, '-i', $args{key};
push @ssh_args, "$args{user}\@$args{host}", "mkdir -p '$remote_path'";
system(@ssh_args);
}
return ($? == 0, $? == 0 ? undef : "Failed to create remote directory");
}
elsif ($type eq 's3' || $type eq 'gdrive') {
my $tmpfile = "/tmp/gniza-rclone-init-$$.conf";
my $conf_content = '';
my $rclone_path = '';
if ($type eq 's3') {
$conf_content = "[remote]\ntype = s3\nprovider = AWS\naccess_key_id = $args{s3_access_key_id}\nsecret_access_key = $args{s3_secret_access_key}\nregion = " . ($args{s3_region} || 'us-east-1') . "\n";
$conf_content .= "endpoint = $args{s3_endpoint}\n" if ($args{s3_endpoint} // '') ne '';
$rclone_path = "remote:$args{s3_bucket}$remote_path";
} else {
$conf_content = "[remote]\ntype = drive\nscope = drive\nservice_account_file = $args{gdrive_service_account_file}\n";
$conf_content .= "root_folder_id = $args{gdrive_root_folder_id}\n" if ($args{gdrive_root_folder_id} // '') ne '';
$rclone_path = "remote:$remote_path";
}
if (open my $fh, '>', $tmpfile) {
print $fh $conf_content;
close $fh;
chmod 0600, $tmpfile;
} else {
return (0, "Failed to write temp rclone config: $!");
}
system('rclone', '--config', $tmpfile, 'mkdir', $rclone_path);
my $ok = ($? == 0);
unlink $tmpfile;
return ($ok, $ok ? undef : "Failed to create remote directory");
}
return (0, "Unknown remote type: $type");
}
# ── Page Wrappers ────────────────────────────────────────────
sub page_header {

View File

@@ -267,6 +267,31 @@ sub handle_add {
}
my ($ok, $err) = GnizaWHM::Config::write($dest, \%data, \@GnizaWHM::Config::REMOTE_KEYS);
if ($ok) {
# Init remote directory structure (like gniza init remote)
my $type = $data{REMOTE_TYPE} || 'ssh';
my %init_args = (
type => $type,
remote_base => $data{REMOTE_BASE} || '/backups',
);
if ($type eq 'ssh') {
$init_args{host} = $data{REMOTE_HOST};
$init_args{port} = $data{REMOTE_PORT} || '22';
$init_args{user} = $data{REMOTE_USER} || 'root';
$init_args{auth_method} = $data{REMOTE_AUTH_METHOD} || 'key';
$init_args{key} = $data{REMOTE_KEY};
$init_args{password} = $data{REMOTE_PASSWORD};
} elsif ($type eq 's3') {
$init_args{s3_access_key_id} = $data{S3_ACCESS_KEY_ID};
$init_args{s3_secret_access_key} = $data{S3_SECRET_ACCESS_KEY};
$init_args{s3_region} = $data{S3_REGION};
$init_args{s3_endpoint} = $data{S3_ENDPOINT};
$init_args{s3_bucket} = $data{S3_BUCKET};
} else {
$init_args{gdrive_service_account_file} = $data{GDRIVE_SERVICE_ACCOUNT_FILE};
$init_args{gdrive_root_folder_id} = $data{GDRIVE_ROOT_FOLDER_ID};
}
GnizaWHM::UI::init_remote_dir(%init_args);
if ($form->{'wizard'}) {
GnizaWHM::UI::set_flash('success', "Remote '$name' created. Now set up a schedule.");
print "Status: 302 Found\r\n";