@@ -251,12 +251,29 @@ string UnknownCmd(string cmd, CmdArgList args) {
251
251
absl::StrJoin (args.begin (), args.end (), " , " , CmdArgListFormatter ()));
252
252
}
253
253
254
- bool IsS3Path (string_view path) {
255
- return absl::StartsWith (path, detail::kS3Prefix );
256
- }
257
-
258
- bool IsGCSPath (string_view path) {
259
- return absl::StartsWith (path, detail::kGCSPrefix );
254
+ std::shared_ptr<detail::SnapshotStorage> CreateCloudSnapshotStorage (std::string_view uri) {
255
+ if (detail::IsS3Path (uri)) {
256
+ #ifdef WITH_AWS
257
+ shard_set->pool ()->GetNextProactor ()->Await ([&] { util::aws::Init (); });
258
+ return std::make_shared<detail::AwsS3SnapshotStorage>(
259
+ absl::GetFlag (FLAGS_s3_endpoint), absl::GetFlag (FLAGS_s3_use_https),
260
+ absl::GetFlag (FLAGS_s3_ec2_metadata), absl::GetFlag (FLAGS_s3_sign_payload));
261
+ #else
262
+ LOG (ERROR) << " Compiled without AWS support" ;
263
+ exit (1 );
264
+ #endif
265
+ } else if (detail::IsGCSPath (uri)) {
266
+ auto gcs = std::make_shared<detail::GcsSnapshotStorage>();
267
+ auto ec = shard_set->pool ()->GetNextProactor ()->Await ([&] { return gcs->Init (3000 ); });
268
+ if (ec) {
269
+ LOG (ERROR) << " Failed to initialize GCS snapshot storage: " << ec.message ();
270
+ exit (1 );
271
+ }
272
+ return gcs;
273
+ } else {
274
+ LOG (ERROR) << " Uknown cloud storage " << uri;
275
+ exit (1 );
276
+ }
260
277
}
261
278
262
279
// Check that if TLS is used at least one form of client authentication is
@@ -854,24 +871,9 @@ void ServerFamily::Init(util::AcceptServer* acceptor, std::vector<facade::Listen
854
871
}
855
872
856
873
string flag_dir = GetFlag (FLAGS_dir);
857
- if (IsS3Path (flag_dir)) {
858
- #ifdef WITH_AWS
859
- shard_set->pool ()->GetNextProactor ()->Await ([&] { util::aws::Init (); });
860
- snapshot_storage_ = std::make_shared<detail::AwsS3SnapshotStorage>(
861
- absl::GetFlag (FLAGS_s3_endpoint), absl::GetFlag (FLAGS_s3_use_https),
862
- absl::GetFlag (FLAGS_s3_ec2_metadata), absl::GetFlag (FLAGS_s3_sign_payload));
863
- #else
864
- LOG (ERROR) << " Compiled without AWS support" ;
865
- exit (1 );
866
- #endif
867
- } else if (IsGCSPath (flag_dir)) {
868
- auto gcs = std::make_shared<detail::GcsSnapshotStorage>();
869
- auto ec = shard_set->pool ()->GetNextProactor ()->Await ([&] { return gcs->Init (3000 ); });
870
- if (ec) {
871
- LOG (ERROR) << " Failed to initialize GCS snapshot storage: " << ec.message ();
872
- exit (1 );
873
- }
874
- snapshot_storage_ = std::move (gcs);
874
+
875
+ if (detail::IsCloudPath (flag_dir)) {
876
+ snapshot_storage_ = CreateCloudSnapshotStorage (flag_dir);
875
877
} else if (fq_threadpool_) {
876
878
snapshot_storage_ = std::make_shared<detail::FileSnapshotStorage>(fq_threadpool_.get ());
877
879
} else {
@@ -1655,10 +1657,11 @@ GenericError ServerFamily::DoSave(bool ignore_state) {
1655
1657
CHECK_NOTNULL (cid);
1656
1658
boost::intrusive_ptr<Transaction> trans (new Transaction{cid});
1657
1659
trans->InitByArgs (&namespaces->GetDefaultNamespace (), 0 , {});
1658
- return DoSave (absl::GetFlag (FLAGS_df_snapshot_format), {}, trans.get (), ignore_state);
1660
+ return DoSave (SaveCmdOptions{absl::GetFlag (FLAGS_df_snapshot_format), {}, {}}, trans.get (),
1661
+ ignore_state);
1659
1662
}
1660
1663
1661
- GenericError ServerFamily::DoSaveCheckAndStart (bool new_version, string_view basename ,
1664
+ GenericError ServerFamily::DoSaveCheckAndStart (const SaveCmdOptions& save_cmd_opts ,
1662
1665
Transaction* trans, bool ignore_state) {
1663
1666
auto state = ServerState::tlocal ()->gstate ();
1664
1667
@@ -1674,10 +1677,13 @@ GenericError ServerFamily::DoSaveCheckAndStart(bool new_version, string_view bas
1674
1677
" SAVING - can not save database" };
1675
1678
}
1676
1679
1677
- VLOG (1 ) << " Saving snapshot to " << basename;
1680
+ auto snapshot_storage = save_cmd_opts.cloud_uri .empty ()
1681
+ ? snapshot_storage_
1682
+ : CreateCloudSnapshotStorage (save_cmd_opts.cloud_uri );
1678
1683
1679
1684
save_controller_ = make_unique<SaveStagesController>(detail::SaveStagesInputs{
1680
- new_version, basename, trans, &service_, fq_threadpool_.get (), snapshot_storage_});
1685
+ save_cmd_opts.new_version , save_cmd_opts.cloud_uri , save_cmd_opts.basename , trans,
1686
+ &service_, fq_threadpool_.get (), snapshot_storage});
1681
1687
1682
1688
auto res = save_controller_->InitResourcesAndStart ();
1683
1689
@@ -1714,9 +1720,9 @@ GenericError ServerFamily::WaitUntilSaveFinished(Transaction* trans, bool ignore
1714
1720
return save_info.error ;
1715
1721
}
1716
1722
1717
- GenericError ServerFamily::DoSave (bool new_version, string_view basename , Transaction* trans,
1723
+ GenericError ServerFamily::DoSave (const SaveCmdOptions& save_cmd_opts , Transaction* trans,
1718
1724
bool ignore_state) {
1719
- if (auto ec = DoSaveCheckAndStart (new_version, basename , trans, ignore_state); ec) {
1725
+ if (auto ec = DoSaveCheckAndStart (save_cmd_opts , trans, ignore_state); ec) {
1720
1726
return ec;
1721
1727
}
1722
1728
@@ -2078,46 +2084,61 @@ void ServerFamily::BgSaveFb(boost::intrusive_ptr<Transaction> trans) {
2078
2084
}
2079
2085
}
2080
2086
2081
- std::optional<ServerFamily::VersionBasename > ServerFamily::GetVersionAndBasename (
2082
- CmdArgList args, SinkReplyBuilder* builder) {
2083
- if (args.size () > 2 ) {
2087
+ std::optional<SaveCmdOptions > ServerFamily::GetSaveCmdOpts (CmdArgList args,
2088
+ SinkReplyBuilder* builder) {
2089
+ if (args.size () > 3 ) {
2084
2090
builder->SendError (kSyntaxErr );
2085
2091
return {};
2086
2092
}
2087
2093
2088
- bool new_version = absl::GetFlag (FLAGS_df_snapshot_format);
2094
+ SaveCmdOptions save_cmd_opts;
2095
+ save_cmd_opts.new_version = absl::GetFlag (FLAGS_df_snapshot_format);
2089
2096
2090
2097
if (args.size () >= 1 ) {
2091
2098
string sub_cmd = absl::AsciiStrToUpper (ArgS (args, 0 ));
2092
2099
if (sub_cmd == " DF" ) {
2093
- new_version = true ;
2100
+ save_cmd_opts. new_version = true ;
2094
2101
} else if (sub_cmd == " RDB" ) {
2095
- new_version = false ;
2102
+ save_cmd_opts. new_version = false ;
2096
2103
} else {
2097
2104
builder->SendError (UnknownSubCmd (sub_cmd, " SAVE" ), kSyntaxErrType );
2098
2105
return {};
2099
2106
}
2100
2107
}
2101
2108
2102
- string_view basename;
2103
- if (args.size () == 2 ) {
2104
- basename = ArgS (args, 1 );
2109
+ if (args.size () >= 2 ) {
2110
+ if (detail::IsS3Path (ArgS (args, 1 ))) {
2111
+ #ifdef WITH_AWS
2112
+ save_cmd_opts.cloud_uri = ArgS (args, 1 );
2113
+ #else
2114
+ LOG (ERROR) << " Compiled without AWS support" ;
2115
+ exit (1 );
2116
+ #endif
2117
+ } else if (detail::IsGCSPath (ArgS (args, 1 ))) {
2118
+ save_cmd_opts.cloud_uri = ArgS (args, 1 );
2119
+ } else {
2120
+ // no cloud_uri get basename and return
2121
+ save_cmd_opts.basename = ArgS (args, 1 );
2122
+ return save_cmd_opts;
2123
+ }
2124
+ // cloud_uri is set so get basename if provided
2125
+ if (args.size () == 3 ) {
2126
+ save_cmd_opts.basename = ArgS (args, 2 );
2127
+ }
2105
2128
}
2106
2129
2107
- return ServerFamily::VersionBasename{new_version, basename} ;
2130
+ return save_cmd_opts ;
2108
2131
}
2109
2132
2110
- // BGSAVE [DF|RDB] [basename ]
2133
+ // SAVE [DF|RDB] [CLOUD_URI] [BASENAME ]
2111
2134
// TODO add missing [SCHEDULE]
2112
2135
void ServerFamily::BgSave (CmdArgList args, const CommandContext& cmd_cntx) {
2113
- auto maybe_res = GetVersionAndBasename (args, cmd_cntx.rb );
2136
+ auto maybe_res = GetSaveCmdOpts (args, cmd_cntx.rb );
2114
2137
if (!maybe_res) {
2115
2138
return ;
2116
2139
}
2117
2140
2118
- const auto [version, basename] = *maybe_res;
2119
-
2120
- if (auto ec = DoSaveCheckAndStart (version, basename, cmd_cntx.tx ); ec) {
2141
+ if (auto ec = DoSaveCheckAndStart (*maybe_res, cmd_cntx.tx ); ec) {
2121
2142
cmd_cntx.rb ->SendError (ec.Format ());
2122
2143
return ;
2123
2144
}
@@ -2127,18 +2148,16 @@ void ServerFamily::BgSave(CmdArgList args, const CommandContext& cmd_cntx) {
2127
2148
cmd_cntx.rb ->SendOk ();
2128
2149
}
2129
2150
2130
- // SAVE [DF|RDB] [basename ]
2151
+ // SAVE [DF|RDB] [CLOUD_URI] [BASENAME ]
2131
2152
// Allows saving the snapshot of the dataset on disk, potentially overriding the format
2132
2153
// and the snapshot name.
2133
2154
void ServerFamily::Save (CmdArgList args, const CommandContext& cmd_cntx) {
2134
- auto maybe_res = GetVersionAndBasename (args, cmd_cntx.rb );
2155
+ auto maybe_res = GetSaveCmdOpts (args, cmd_cntx.rb );
2135
2156
if (!maybe_res) {
2136
2157
return ;
2137
2158
}
2138
2159
2139
- const auto [version, basename] = *maybe_res;
2140
-
2141
- GenericError ec = DoSave (version, basename, cmd_cntx.tx );
2160
+ GenericError ec = DoSave (*maybe_res, cmd_cntx.tx );
2142
2161
if (ec) {
2143
2162
cmd_cntx.rb ->SendError (ec.Format ());
2144
2163
} else {
0 commit comments