Merge lp:~xavi-garcia-mena/keeper/accounts-selection into lp:keeper/devel

Proposed by Xavi Garcia
Status: Needs review
Proposed branch: lp:~xavi-garcia-mena/keeper/accounts-selection
Merge into: lp:keeper/devel
Prerequisite: lp:~unity-api-team/keeper/sf-errors-dbus-interface
Diff against target: 1282 lines (+375/-102)
28 files modified
include/client/client.h (+8/-5)
include/client/keeper-errors.h (+2/-1)
src/cli/command-line-client-view.cpp (+3/-0)
src/cli/command-line-client.cpp (+23/-7)
src/cli/command-line-client.h (+6/-3)
src/cli/command-line.cpp (+56/-10)
src/cli/command-line.h (+4/-1)
src/cli/main.cpp (+14/-3)
src/client/client.cpp (+33/-10)
src/qdbus-stubs/com.canonical.keeper.User.xml (+44/-0)
src/service/backup-choices.cpp (+1/-1)
src/service/backup-choices.h (+1/-1)
src/service/keeper-user.cpp (+17/-6)
src/service/keeper-user.h (+5/-3)
src/service/keeper.cpp (+45/-12)
src/service/keeper.h (+7/-3)
src/service/metadata-provider.h (+1/-1)
src/service/restore-choices.cpp (+2/-1)
src/service/restore-choices.h (+1/-1)
src/service/task-manager.cpp (+10/-9)
src/service/task-manager.h (+2/-2)
src/storage-framework/storage_framework_client.cpp (+73/-10)
src/storage-framework/storage_framework_client.h (+5/-0)
tests/integration/helpers/helpers-test-failure.cpp (+1/-1)
tests/integration/helpers/helpers-test.cc (+6/-6)
tests/integration/helpers/restore-test.cpp (+1/-1)
tests/utils/storage-framework-local.cpp (+2/-2)
tests/utils/storage-framework-local.h (+2/-2)
To merge this branch: bzr merge lp:~xavi-garcia-mena/keeper/accounts-selection
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
unity-api-1-bot continuous-integration Approve
Review via email: mp+314445@code.launchpad.net

Commit message

This branch adds the account selection to the service and command line client.

Description of the change

This branch adds the account selection to the service and command line client.

It also adds the option to cancel a backup/restore from the command line client when pressing Ctrl+C

If the account id is empty it selects the first available account.

To post a comment you must log in.
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Xavi Garcia (xavi-garcia-mena) wrote :

Oups, I forgot to fix the tests after the interface change..

Please, hold on this until Jenkins in happy.

142. By Xavi Garcia

Tests fixed after dbus interface change

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:142
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/168/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1342
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1349
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1127
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1127/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1127
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1127/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1127
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1127/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1127
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1127/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1127
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1127/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1127
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1127/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/168/rebuild

review: Approve (continuous-integration)
Revision history for this message
Xavi Garcia (xavi-garcia-mena) wrote :

Green light! Ready for review! :)

Revision history for this message
Charles Kerr (charlesk) wrote :

Couplea very minor suggestions. Overall looks fine; pretty straightforward patch

review: Approve
143. By Xavi Garcia

Changed as suggested in review

Revision history for this message
Xavi Garcia (xavi-garcia-mena) wrote :

Thanks for the review, Charles!
I've updated the branch to include your suggestions.

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:143
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/176/
Executed test runs:

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/176/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:143
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/177/
Executed test runs:

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/177/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:143
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/178/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1359/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1366
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1144
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1144/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1144
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1144/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1144
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1144/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1144
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1144/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1144
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1144/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1144/console

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/178/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:143
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/179/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1370
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1377
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1155
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1155/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1155
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1155/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1155
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1155/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1155
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1155/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1155
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1155/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1155
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1155/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-keeper-ci/179/rebuild

review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

re-approving

review: Approve

Unmerged revisions

143. By Xavi Garcia

Changed as suggested in review

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/client/client.h'
2--- include/client/client.h 2017-01-12 11:31:45 +0000
3+++ include/client/client.h 2017-01-12 11:31:45 +0000
4@@ -56,19 +56,22 @@
5
6 Q_INVOKABLE QString getBackupName(QString uuid);
7 Q_INVOKABLE void enableBackup(QString uuid, bool enabled);
8- Q_INVOKABLE void startBackup();
9+ Q_INVOKABLE void startBackup(QString const & storage);
10
11 Q_INVOKABLE void enableRestore(QString uuid, bool enabled);
12- Q_INVOKABLE void startRestore();
13+ Q_INVOKABLE void startRestore(QString const & storage);
14+
15+ Q_INVOKABLE void cancel();
16
17 // C++
18 public:
19 keeper::Items getBackupChoices(keeper::Error & error) const;
20- keeper::Items getRestoreChoices(keeper::Error & error) const;
21- void startBackup(QStringList const& uuids) const;
22- void startRestore(QStringList const& uuids) const;
23+ keeper::Items getRestoreChoices(QString const & storage, keeper::Error & error) const;
24+ void startBackup(QStringList const& uuids, QString const & storage) const;
25+ void startRestore(QStringList const& uuids, QString const & storage) const;
26
27 keeper::Items getState() const;
28+ QStringList getStorageAccounts() const;
29
30 Q_SIGNALS:
31 void statusChanged();
32
33=== modified file 'include/client/keeper-errors.h'
34--- include/client/keeper-errors.h 2017-01-12 11:31:45 +0000
35+++ include/client/keeper-errors.h 2017-01-12 11:31:45 +0000
36@@ -44,7 +44,8 @@
37 READING_REMOTE_FILE,
38 REMOTE_DIR_NOT_EXISTS,
39 NO_REMOTE_ACCOUNTS,
40- NO_REMOTE_ROOTS
41+ NO_REMOTE_ROOTS,
42+ ACCOUNT_NOT_FOUND
43 };
44
45 Error convert_from_dbus_variant(const QVariant & value, bool *conversion_ok = nullptr);
46
47=== modified file 'src/cli/command-line-client-view.cpp'
48--- src/cli/command-line-client-view.cpp 2017-01-12 11:31:45 +0000
49+++ src/cli/command-line-client-view.cpp 2017-01-12 11:31:45 +0000
50@@ -177,6 +177,9 @@
51 case keeper::Error::NO_REMOTE_ROOTS:
52 ret = QStringLiteral("No remote root accounts were found");
53 break;
54+ case keeper::Error::ACCOUNT_NOT_FOUND:
55+ ret = QStringLiteral("The storage account was not found");
56+ break;
57 }
58 return ret;
59 }
60
61=== modified file 'src/cli/command-line-client.cpp'
62--- src/cli/command-line-client.cpp 2017-01-12 11:31:45 +0000
63+++ src/cli/command-line-client.cpp 2017-01-12 11:31:45 +0000
64@@ -40,7 +40,7 @@
65
66 CommandLineClient::~CommandLineClient() = default;
67
68-void CommandLineClient::run_list_sections(bool remote)
69+void CommandLineClient::run_list_sections(bool remote, QString const & storage)
70 {
71 keeper::Items choices_values;
72 keeper::Error error;
73@@ -52,13 +52,18 @@
74 }
75 else
76 {
77- choices_values = keeper_client_->getRestoreChoices(error);
78+ choices_values = keeper_client_->getRestoreChoices(storage, error);
79 check_for_choices_error(error);
80 list_restore_sections(choices_values);
81 }
82 }
83
84-void CommandLineClient::run_backup(QStringList & sections)
85+void CommandLineClient::run_list_storage_accounts()
86+{
87+ list_storage_accounts(keeper_client_->getStorageAccounts());
88+}
89+
90+void CommandLineClient::run_backup(QStringList & sections, QString const & storage)
91 {
92 auto unhandled_sections = sections;
93 keeper::Error error;
94@@ -101,15 +106,16 @@
95 {
96 keeper_client_->enableBackup(uuid, true);
97 }
98- keeper_client_->startBackup();
99+ keeper_client_->startBackup(storage);
100 view_->start_printing_tasks();
101 }
102
103-void CommandLineClient::run_restore(QStringList & sections)
104+void CommandLineClient::run_restore(QStringList & sections, QString const & storage)
105 {
106 auto unhandled_sections = sections;
107 keeper::Error error;
108- auto choices_values = keeper_client_->getRestoreChoices(error);
109+
110+ auto choices_values = keeper_client_->getRestoreChoices(storage, error);
111 check_for_choices_error(error);
112 QStringList uuids;
113
114@@ -149,10 +155,15 @@
115 {
116 keeper_client_->enableRestore(uuid, true);
117 }
118- keeper_client_->startRestore();
119+ keeper_client_->startRestore(storage);
120 view_->start_printing_tasks();
121 }
122
123+void CommandLineClient::run_cancel() const
124+{
125+ keeper_client_->cancel();
126+}
127+
128 void CommandLineClient::list_backup_sections(keeper::Items const & choices_values)
129 {
130 QStringList sections;
131@@ -195,6 +206,11 @@
132 view_->print_sections(sections);
133 }
134
135+void CommandLineClient::list_storage_accounts(QStringList const & accounts)
136+{
137+ view_->print_sections(accounts);
138+}
139+
140 void CommandLineClient::on_progress_changed()
141 {
142 view_->progress_changed(keeper_client_->progress());
143
144=== modified file 'src/cli/command-line-client.h'
145--- src/cli/command-line-client.h 2017-01-12 11:31:45 +0000
146+++ src/cli/command-line-client.h 2017-01-12 11:31:45 +0000
147@@ -36,9 +36,11 @@
148
149 Q_DISABLE_COPY(CommandLineClient)
150
151- void run_list_sections(bool remote);
152- void run_backup(QStringList & sections);
153- void run_restore(QStringList & sections);
154+ void run_list_sections(bool remote, QString const & storage = "");
155+ void run_list_storage_accounts();
156+ void run_backup(QStringList & sections, QString const & storage);
157+ void run_restore(QStringList & sections, QString const & storage);
158+ void run_cancel() const;
159
160 private Q_SLOTS:
161 void on_progress_changed();
162@@ -49,6 +51,7 @@
163 bool find_choice_value(QVariantMap const & choice, QString const & id, QVariant & value);
164 void list_backup_sections(keeper::Items const & choices);
165 void list_restore_sections(keeper::Items const & choices);
166+ void list_storage_accounts(QStringList const & accounts);
167 void check_for_choices_error(keeper::Error error);
168 QScopedPointer<KeeperClient> keeper_client_;
169 QScopedPointer<CommandLineClientView> view_;
170
171=== modified file 'src/cli/command-line.cpp'
172--- src/cli/command-line.cpp 2016-12-16 09:34:05 +0000
173+++ src/cli/command-line.cpp 2017-01-12 11:31:45 +0000
174@@ -26,21 +26,23 @@
175 namespace
176 {
177 // arguments
178- constexpr const char ARGUMENT_LIST_SECTIONS[] = "list-sections";
179- constexpr const char ARGUMENT_BACKUP[] = "backup";
180- constexpr const char ARGUMENT_RESTORE[] = "restore";
181+ constexpr const char ARGUMENT_LIST_SECTIONS[] = "list-sections";
182+ constexpr const char ARGUMENT_LIST_STORAGE_ACCOUNTS[] = "list-storage-configs";
183+ constexpr const char ARGUMENT_BACKUP[] = "backup";
184+ constexpr const char ARGUMENT_RESTORE[] = "restore";
185
186 // argument descriptions
187- constexpr const char ARGUMENT_LIST_SECTIONS_DESCRIPTION[] = "List the sections available to backup";
188- constexpr const char ARGUMENT_BACKUP_DESCRIPTION[] = "Starts a backup";
189- constexpr const char ARGUMENT_RESTORE_DESCRIPTION[] = "Starts a restore";
190+ constexpr const char ARGUMENT_LIST_SECTIONS_DESCRIPTION[] = "List the sections available to backup";
191+ constexpr const char ARGUMENT_LIST_STORAGE_ACCOUNTS_DESCRIPTION[] = "List the available storage accounts";
192+ constexpr const char ARGUMENT_BACKUP_DESCRIPTION[] = "Starts a backup";
193+ constexpr const char ARGUMENT_RESTORE_DESCRIPTION[] = "Starts a restore";
194
195 // options
196 constexpr const char OPTION_STORAGE[] = "storage";
197 constexpr const char OPTION_SECTIONS[] = "sections";
198
199 // option descriptions
200- constexpr const char OPTION_STORAGE_DESCRIPTION[] = "Lists the available sections stored at the storage";
201+ constexpr const char OPTION_STORAGE_DESCRIPTION[] = "Defines the available storage to use. Pass 'default' to use the default one";
202 constexpr const char OPTION_SECTIONS_DESCRIPTION[] = "Lists the sections to backup or restore";
203 }
204
205@@ -51,6 +53,7 @@
206 parser_->addHelpOption();
207 parser_->addVersionOption();
208 parser_->addPositionalArgument(ARGUMENT_LIST_SECTIONS, QCoreApplication::translate("main", ARGUMENT_LIST_SECTIONS_DESCRIPTION));
209+ parser_->addPositionalArgument(ARGUMENT_LIST_STORAGE_ACCOUNTS, QCoreApplication::translate("main", ARGUMENT_LIST_STORAGE_ACCOUNTS_DESCRIPTION));
210 parser_->addPositionalArgument(ARGUMENT_BACKUP, QCoreApplication::translate("main", ARGUMENT_BACKUP_DESCRIPTION));
211 parser_->addPositionalArgument(ARGUMENT_RESTORE, QCoreApplication::translate("main", ARGUMENT_RESTORE_DESCRIPTION));
212 }
213@@ -71,6 +74,10 @@
214 {
215 return handle_list_sections(app, cmd_args);
216 }
217+ else if (args.at(0) == ARGUMENT_LIST_STORAGE_ACCOUNTS)
218+ {
219+ return handle_list_storage_accounts(app, cmd_args);
220+ }
221 else if (args.at(0) == ARGUMENT_BACKUP)
222 {
223 return handle_backup(app, cmd_args);
224@@ -103,7 +110,9 @@
225
226 parser_->addOptions({
227 {{"r", OPTION_STORAGE},
228- QCoreApplication::translate("main", OPTION_STORAGE_DESCRIPTION)},
229+ QCoreApplication::translate("main", OPTION_STORAGE_DESCRIPTION),
230+ QCoreApplication::translate("main", OPTION_STORAGE_DESCRIPTION)
231+ },
232 });
233 parser_->process(app);
234
235@@ -113,6 +122,7 @@
236 if (parser_->isSet(OPTION_STORAGE))
237 {
238 cmd_args.cmd = CommandLineParser::Command::LIST_REMOTE_SECTIONS;
239+ cmd_args.storage = get_storage_string(parser_->value(OPTION_STORAGE));
240 }
241 else
242 {
243@@ -122,6 +132,17 @@
244 return true;
245 }
246
247+bool CommandLineParser::handle_list_storage_accounts(QCoreApplication const & app, CommandArgs & cmd_args)
248+{
249+ parser_->process(app);
250+ // it didn't exit... we're good
251+ cmd_args.sections.clear();
252+ cmd_args.storage.clear();
253+ cmd_args.cmd = CommandLineParser::Command::LIST_STORAGE_ACCOUNTS;
254+
255+ return true;
256+}
257+
258 bool CommandLineParser::handle_backup(QCoreApplication const & app, CommandLineParser::CommandArgs & cmd_args)
259 {
260 parser_->clearPositionalArguments();
261@@ -132,6 +153,10 @@
262 QCoreApplication::translate("main", OPTION_SECTIONS_DESCRIPTION),
263 QCoreApplication::translate("main", OPTION_SECTIONS_DESCRIPTION)
264 },
265+ {{"r", OPTION_STORAGE},
266+ QCoreApplication::translate("main", OPTION_STORAGE_DESCRIPTION),
267+ QCoreApplication::translate("main", OPTION_STORAGE_DESCRIPTION)
268+ },
269 });
270 parser_->process(app);
271
272@@ -144,6 +169,10 @@
273 std::cerr << "You need to specify some sections to run a backup." << std::endl;
274 return false;
275 }
276+ if (parser_->isSet(OPTION_STORAGE))
277+ {
278+ cmd_args.storage = get_storage_string(parser_->value(OPTION_STORAGE));
279+ }
280 cmd_args.sections = parser_->value(OPTION_SECTIONS).split(',');
281
282 return true;
283@@ -159,18 +188,26 @@
284 QCoreApplication::translate("main", OPTION_SECTIONS_DESCRIPTION),
285 QCoreApplication::translate("main", OPTION_SECTIONS_DESCRIPTION)
286 },
287+ {{"r", OPTION_STORAGE},
288+ QCoreApplication::translate("main", OPTION_STORAGE_DESCRIPTION),
289+ QCoreApplication::translate("main", OPTION_STORAGE_DESCRIPTION)
290+ },
291 });
292 parser_->process(app);
293
294 // it didn't exit... we're good
295- cmd_args.sections = QStringList();
296- cmd_args.storage = QString();
297+ cmd_args.sections.clear();
298+ cmd_args.storage.clear();
299 cmd_args.cmd = CommandLineParser::Command::RESTORE;
300 if (!parser_->isSet(OPTION_SECTIONS))
301 {
302 std::cerr << "You need to specify some sections to run a restore." << std::endl;
303 return false;
304 }
305+ if (parser_->isSet(OPTION_STORAGE))
306+ {
307+ cmd_args.storage = get_storage_string(parser_->value(OPTION_STORAGE));
308+ }
309 cmd_args.sections = parser_->value(OPTION_SECTIONS).split(',');
310
311 return true;
312@@ -186,3 +223,12 @@
313 }
314 return true;
315 }
316+
317+QString CommandLineParser::get_storage_string(QString const & value)
318+{
319+ if (value == "default")
320+ {
321+ return QString();
322+ }
323+ return value;
324+}
325
326=== modified file 'src/cli/command-line.h'
327--- src/cli/command-line.h 2016-11-30 14:46:29 +0000
328+++ src/cli/command-line.h 2017-01-12 11:31:45 +0000
329@@ -27,7 +27,7 @@
330 {
331 public:
332 Q_ENUMS(Command)
333- enum class Command {LIST_LOCAL_SECTIONS, LIST_REMOTE_SECTIONS, BACKUP, RESTORE};
334+ enum class Command {LIST_LOCAL_SECTIONS, LIST_REMOTE_SECTIONS, LIST_STORAGE_ACCOUNTS, BACKUP, RESTORE};
335 struct CommandArgs
336 {
337 Command cmd;
338@@ -43,10 +43,13 @@
339
340 private:
341 bool handle_list_sections(QCoreApplication const & app, CommandArgs & cmd_args);
342+ bool handle_list_storage_accounts(QCoreApplication const & app, CommandArgs & cmd_args);
343 bool handle_backup(QCoreApplication const & app, CommandArgs & cmd_args);
344 bool handle_restore(QCoreApplication const & app, CommandArgs & cmd_args);
345
346 bool check_number_of_args(QStringList const & args);
347
348+ QString get_storage_string(QString const & value);
349+
350 QSharedPointer<QCommandLineParser> parser_;
351 };
352
353=== modified file 'src/cli/main.cpp'
354--- src/cli/main.cpp 2016-11-30 14:46:29 +0000
355+++ src/cli/main.cpp 2017-01-12 11:31:45 +0000
356@@ -22,6 +22,7 @@
357
358 #include <dbus-types.h>
359 #include <util/logging.h>
360+#include "util/unix-signal-handler.h"
361
362 #include <keeper_user_interface.h>
363
364@@ -43,6 +44,12 @@
365 DBusTypes::registerMetaTypes();
366 std::srand(unsigned(std::time(nullptr)));
367
368+ util::UnixSignalHandler handler([]{
369+ CommandLineClient client;
370+ client.run_cancel();
371+ });
372+ handler.setupUnixSignalHandlers();
373+
374 // boilerplate locale
375 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
376 setlocale(LC_ALL, "");
377@@ -63,15 +70,19 @@
378 client.run_list_sections(false);
379 exit(0);
380 break;
381+ case CommandLineParser::Command::LIST_STORAGE_ACCOUNTS:
382+ client.run_list_storage_accounts();
383+ exit(0);
384+ break;
385 case CommandLineParser::Command::LIST_REMOTE_SECTIONS:
386- client.run_list_sections(true);
387+ client.run_list_sections(true, cmd_args.storage);
388 exit(0);
389 break;
390 case CommandLineParser::Command::BACKUP:
391- client.run_backup(cmd_args.sections);
392+ client.run_backup(cmd_args.sections, cmd_args.storage);
393 break;
394 case CommandLineParser::Command::RESTORE:
395- client.run_restore(cmd_args.sections);
396+ client.run_restore(cmd_args.sections, cmd_args.storage);
397 break;
398 };
399 }
400
401=== modified file 'src/client/client.cpp'
402--- src/client/client.cpp 2017-01-12 11:31:45 +0000
403+++ src/client/client.cpp 2017-01-12 11:31:45 +0000
404@@ -199,7 +199,7 @@
405 enableBackup(uuid, enabled);
406 }
407
408-void KeeperClient::startBackup()
409+void KeeperClient::startBackup(QString const & storage)
410 {
411 // Determine which backups are enabled, and start only those
412 QStringList backupList;
413@@ -213,7 +213,7 @@
414
415 if (!backupList.empty())
416 {
417- startBackup(backupList);
418+ startBackup(backupList, storage);
419
420 d->mode = KeeperClientPrivate::TasksMode::BACKUP_MODE;
421 d->status = "Preparing Backup...";
422@@ -223,7 +223,7 @@
423 }
424 }
425
426-void KeeperClient::startRestore()
427+void KeeperClient::startRestore(QString const & storage)
428 {
429 // Determine which restores are enabled, and start only those
430 QStringList restoreList;
431@@ -237,7 +237,7 @@
432
433 if (!restoreList.empty())
434 {
435- startRestore(restoreList);
436+ startRestore(restoreList, storage);
437
438 d->mode = KeeperClientPrivate::TasksMode::RESTORE_MODE;
439 d->status = "Preparing Restore...";
440@@ -247,6 +247,16 @@
441 }
442 }
443
444+void KeeperClient::cancel()
445+{
446+ QDBusReply<void> cancelReply = d->userIface->call("Cancel");
447+
448+ if (!cancelReply.isValid())
449+ {
450+ qWarning() << "Error canceling" << cancelReply.error().message();
451+ }
452+}
453+
454 QString KeeperClient::getBackupName(QString uuid)
455 {
456 return d->backups.value(uuid).get_display_name();
457@@ -258,15 +268,15 @@
458 return KeeperClientPrivate::getValue(choices, error);
459 }
460
461-keeper::Items KeeperClient::getRestoreChoices(keeper::Error & error) const
462+keeper::Items KeeperClient::getRestoreChoices(QString const & storage, keeper::Error & error) const
463 {
464- QDBusMessage choices = d->userIface->call("GetRestoreChoices");
465+ QDBusMessage choices = d->userIface->call("GetRestoreChoices", storage);
466 return KeeperClientPrivate::getValue(choices, error);
467 }
468
469-void KeeperClient::startBackup(const QStringList& uuids) const
470+void KeeperClient::startBackup(const QStringList& uuids, QString const & storage) const
471 {
472- QDBusReply<void> backupReply = d->userIface->call("StartBackup", uuids);
473+ QDBusReply<void> backupReply = d->userIface->call("StartBackup", uuids, storage);
474
475 if (!backupReply.isValid())
476 {
477@@ -274,9 +284,9 @@
478 }
479 }
480
481-void KeeperClient::startRestore(const QStringList& uuids) const
482+void KeeperClient::startRestore(const QStringList& uuids, QString const & storage) const
483 {
484- QDBusReply<void> backupReply = d->userIface->call("StartRestore", uuids);
485+ QDBusReply<void> backupReply = d->userIface->call("StartRestore", uuids, storage);
486
487 if (!backupReply.isValid())
488 {
489@@ -289,6 +299,19 @@
490 return d->userIface->state();
491 }
492
493+QStringList KeeperClient::getStorageAccounts() const
494+{
495+ QDBusPendingReply<QStringList> accountsReply = d->userIface->call("GetStorageAccounts");
496+
497+ accountsReply.waitForFinished();
498+ if (!accountsReply.isValid())
499+ {
500+ qWarning() << "Error retrieving storage accounts:" << accountsReply.error().message();
501+ }
502+
503+ return accountsReply.value();
504+}
505+
506 void KeeperClient::stateUpdated()
507 {
508 auto states = getState();
509
510=== modified file 'src/qdbus-stubs/com.canonical.keeper.User.xml'
511--- src/qdbus-stubs/com.canonical.keeper.User.xml 2017-01-12 11:31:45 +0000
512+++ src/qdbus-stubs/com.canonical.keeper.User.xml 2017-01-12 11:31:45 +0000
513@@ -32,10 +32,32 @@
514 </doc:description>
515 </doc:doc>
516 </arg>
517+ <arg direction="in" name="storage" type="s">
518+ <doc:doc>
519+ <doc:summary>The storage identifier</doc:summary>
520+ <doc:description>
521+ <doc:para>Because keeper supports multiple storage providers the user can define
522+ which is the storage provider to use.
523+ If the passed storage id is an empty string the default storage provider
524+ will be used.</doc:para>
525+ </doc:description>
526+ </doc:doc>
527+ </arg>
528 </method>
529
530 <method name="GetRestoreChoices">
531 <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="keeper::Items"/>
532+ <arg direction="in" name="storage" type="s">
533+ <doc:doc>
534+ <doc:summary>The storage identifier</doc:summary>
535+ <doc:description>
536+ <doc:para>Because keeper supports multiple storage providers the user can define
537+ which is the storage provider to use.
538+ If the passed storage id is an empty string the default storage provider
539+ will be used.</doc:para>
540+ </doc:description>
541+ </doc:doc>
542+ </arg>
543 <arg direction="out" name="backups" type="a{sa{sv}}">
544 <doc:doc>
545 <doc:summary>The backups which already exist and can be restored</doc:summary>
546@@ -62,6 +84,17 @@
547 </doc:description>
548 </doc:doc>
549 </arg>
550+ <arg direction="in" name="storage" type="s">
551+ <doc:doc>
552+ <doc:summary>The storage identifier</doc:summary>
553+ <doc:description>
554+ <doc:para>Because keeper supports multiple storage providers the user can define
555+ which is the storage provider to use.
556+ If the passed storage id is an empty string the default storage provider
557+ will be used.</doc:para>
558+ </doc:description>
559+ </doc:doc>
560+ </arg>
561 </method>
562
563 <property name="State" type="a{sa{sv}}" access="read">
564@@ -86,6 +119,17 @@
565 </doc:doc>
566 </property>
567
568+ <method name="GetStorageAccounts">
569+ <arg direction="out" name="accounts" type="as">
570+ <doc:doc>
571+ <doc:summary>The list of available storage accounts.</doc:summary>
572+ <doc:description>
573+ <doc:para>An array of the available accounts to choose from to backup/restore</doc:para>
574+ </doc:description>
575+ </doc:doc>
576+ </arg>
577+ </method>
578+
579 <method name="Cancel">
580 <doc:doc>
581 <doc:summary>Cancels the current backup or restore actions.</doc:summary>
582
583=== modified file 'src/service/backup-choices.cpp'
584--- src/service/backup-choices.cpp 2017-01-12 11:31:45 +0000
585+++ src/service/backup-choices.cpp 2017-01-12 11:31:45 +0000
586@@ -59,7 +59,7 @@
587 }
588
589 void
590-BackupChoices::get_backups_async()
591+BackupChoices::get_backups_async(QString const & /*storage*/)
592 {
593 backups_.clear();
594 //
595
596=== modified file 'src/service/backup-choices.h'
597--- src/service/backup-choices.h 2016-10-28 15:11:21 +0000
598+++ src/service/backup-choices.h 2017-01-12 11:31:45 +0000
599@@ -30,5 +30,5 @@
600 explicit BackupChoices(QObject *parent = nullptr);
601 virtual ~BackupChoices();
602 QVector<Metadata> get_backups() const override;
603- void get_backups_async() override;
604+ void get_backups_async(QString const & storage = "") override;
605 };
606
607=== modified file 'src/service/keeper-user.cpp'
608--- src/service/keeper-user.cpp 2017-01-12 11:31:45 +0000
609+++ src/service/keeper-user.cpp 2017-01-12 11:31:45 +0000
610@@ -42,13 +42,13 @@
611 }
612
613 void
614-KeeperUser::StartBackup (const QStringList& keys)
615+KeeperUser::StartBackup (const QStringList& keys, QString const & storage)
616 {
617 Q_ASSERT(calledFromDBus());
618
619 auto bus = connection();
620 auto& msg = message();
621- keeper_.start_tasks(keys, bus, msg);
622+ keeper_.start_tasks(keys, storage, bus, msg);
623 }
624
625 void
626@@ -58,17 +58,17 @@
627 }
628
629 keeper::Items
630-KeeperUser::GetRestoreChoices()
631+KeeperUser::GetRestoreChoices(QString const & storage)
632 {
633 Q_ASSERT(calledFromDBus());
634
635 auto bus = connection();
636 auto& msg = message();
637- return keeper_.get_restore_choices(bus, msg);
638+ return keeper_.get_restore_choices(storage, bus, msg);
639 }
640
641 void
642-KeeperUser::StartRestore (const QStringList& keys)
643+KeeperUser::StartRestore (const QStringList& keys, QString const & storage)
644 {
645 Q_ASSERT(calledFromDBus());
646
647@@ -78,7 +78,7 @@
648 // will be found as a backup uuid.
649 // Just clear the backup cache to avoid that.
650 keeper_.invalidate_choices_cache();
651- keeper_.start_tasks(keys, bus, msg);
652+ keeper_.start_tasks(keys, storage, bus, msg);
653 }
654
655 keeper::Items
656@@ -86,3 +86,14 @@
657 {
658 return keeper_.get_state();
659 }
660+
661+QStringList
662+KeeperUser::GetStorageAccounts()
663+{
664+ Q_ASSERT(calledFromDBus());
665+
666+ auto bus = connection();
667+ auto& msg = message();
668+
669+ return keeper_.get_storage_accounts(bus, msg);
670+}
671
672=== modified file 'src/service/keeper-user.h'
673--- src/service/keeper-user.h 2017-01-12 11:31:45 +0000
674+++ src/service/keeper-user.h 2017-01-12 11:31:45 +0000
675@@ -50,13 +50,15 @@
676 public Q_SLOTS:
677
678 keeper::Items GetBackupChoices();
679- void StartBackup(const QStringList&);
680+ void StartBackup(const QStringList&, QString const & storage);
681
682- keeper::Items GetRestoreChoices();
683- void StartRestore(const QStringList&);
684+ keeper::Items GetRestoreChoices(QString const & storage);
685+ void StartRestore(const QStringList&, QString const & storage);
686
687 void Cancel();
688
689+ QStringList GetStorageAccounts();
690+
691 private:
692
693 Keeper& keeper_;
694
695=== modified file 'src/service/keeper.cpp'
696--- src/service/keeper.cpp 2017-01-12 11:31:45 +0000
697+++ src/service/keeper.cpp 2017-01-12 11:31:45 +0000
698@@ -90,6 +90,7 @@
699 Q_DISABLE_COPY(KeeperPrivate)
700
701 void start_tasks(QStringList const & uuids,
702+ QString const & storage,
703 QDBusConnection bus,
704 QDBusMessage const & msg)
705 {
706@@ -108,12 +109,12 @@
707 connections_.connect_oneshot(
708 this,
709 &KeeperPrivate::backup_choices_ready,
710- std::function<void()>{[this, uuids, msg, bus, get_tasks](){
711+ std::function<void()>{[this, uuids, msg, bus, get_tasks, storage](){
712 auto tasks = get_tasks(cached_backup_choices_, uuids);
713 if (!tasks.empty())
714 {
715 auto unhandled = QSet<QString>::fromList(uuids);
716- if (task_manager_.start_backup(tasks.values()))
717+ if (task_manager_.start_backup(tasks.values(), storage))
718 unhandled.subtract(QSet<QString>::fromList(tasks.keys()));
719
720 check_for_unhandled_tasks_and_reply(unhandled, bus, msg);
721@@ -124,14 +125,14 @@
722 connections_.connect_oneshot(
723 this,
724 &KeeperPrivate::restore_choices_ready,
725- std::function<void(keeper::Error)>{[this, uuids, msg, bus, get_tasks](keeper::Error error){
726+ std::function<void(keeper::Error)>{[this, uuids, msg, bus, get_tasks, storage](keeper::Error error){
727 qDebug() << "Choices ready";
728 auto unhandled = QSet<QString>::fromList(uuids);
729 if (error == keeper::Error::OK)
730 {
731 auto restore_tasks = get_tasks(cached_restore_choices_, uuids);
732 qDebug() << "After getting tasks...";
733- if (!restore_tasks.empty() && task_manager_.start_restore(restore_tasks.values()))
734+ if (!restore_tasks.empty() && task_manager_.start_restore(restore_tasks.values(), storage))
735 unhandled.subtract(QSet<QString>::fromList(restore_tasks.keys()));
736 }
737 check_for_unhandled_tasks_and_reply(unhandled, bus, msg);
738@@ -159,7 +160,7 @@
739 }
740 }
741
742- void get_choices(const QSharedPointer<MetadataProvider> & provider, ChoicesType type)
743+ void get_choices(const QSharedPointer<MetadataProvider> & provider, ChoicesType type, QString const & storage = "")
744 {
745 bool check_empty = (type == KeeperPrivate::ChoicesType::BACKUP_CHOICES)
746 ? cached_backup_choices_.isEmpty() : cached_restore_choices_.isEmpty();
747@@ -185,7 +186,7 @@
748 emit_choices_ready(type, error);
749 }}
750 );
751- provider->get_backups_async();
752+ provider->get_backups_async(storage);
753 }
754 else
755 {
756@@ -223,10 +224,11 @@
757 return keeper::Items();
758 }
759
760- keeper::Items get_restore_choices_var_dict_map(QDBusConnection bus,
761+ keeper::Items get_restore_choices_var_dict_map(QString const & storage,
762+ QDBusConnection bus,
763 QDBusMessage const & msg)
764 {
765- qDebug() << "Getting restores --------------------------------";
766+ qDebug() << "Getting restores for storage " << storage << " --------------------------------";
767 cached_restore_choices_.clear();
768 connections_.connect_oneshot(
769 this,
770@@ -250,7 +252,7 @@
771 }
772 }}
773 );
774- get_choices(restore_choices_, KeeperPrivate::ChoicesType::RESTORES_CHOICES);
775+ get_choices(restore_choices_, KeeperPrivate::ChoicesType::RESTORES_CHOICES, storage);
776 msg.setDelayedReply(true);
777 return keeper::Items();
778 }
779@@ -347,6 +349,25 @@
780 cached_backup_choices_.clear();
781 }
782
783+ QStringList get_storage_accounts(QDBusConnection bus,
784+ QDBusMessage const & msg)
785+ {
786+ connections_.connect_future(
787+ storage_->get_accounts(),
788+ std::function<void(QStringList const &)>{
789+ [this, msg, bus](QStringList const& accounts){
790+ qDebug() << "get_storage_accounts() finished";
791+ // reply now to the dbus call
792+ auto reply = msg.createReply();
793+ reply << QVariant::fromValue(accounts);
794+ bus.send(reply);
795+ }
796+ }
797+ );
798+ msg.setDelayedReply(true);
799+ return QStringList();
800+ }
801+
802 Q_SIGNALS:
803 void backup_choices_ready(keeper::Error error);
804 void restore_choices_ready(keeper::Error error);
805@@ -401,12 +422,13 @@
806
807 void
808 Keeper::start_tasks(QStringList const & uuids,
809+ QString const & storage,
810 QDBusConnection bus,
811 QDBusMessage const & msg)
812 {
813 Q_D(Keeper);
814
815- d->start_tasks(uuids, bus, msg);
816+ d->start_tasks(uuids, storage, bus, msg);
817 }
818
819 QDBusUnixFileDescriptor
820@@ -438,12 +460,13 @@
821 }
822
823 keeper::Items
824-Keeper::get_restore_choices(QDBusConnection bus,
825+Keeper::get_restore_choices(QString const & storage,
826+ QDBusConnection bus,
827 QDBusMessage const & msg)
828 {
829 Q_D(Keeper);
830
831- return d->get_restore_choices_var_dict_map(bus,msg);
832+ return d->get_restore_choices_var_dict_map(storage, bus, msg);
833 }
834
835 keeper::Items
836@@ -470,4 +493,14 @@
837 d->invalidate_choices_cache();
838 }
839
840+QStringList
841+Keeper::get_storage_accounts(QDBusConnection bus,
842+ QDBusMessage const & message)
843+{
844+ Q_D(Keeper);
845+
846+ return d->get_storage_accounts(bus,message);
847+}
848+
849+
850 #include "keeper.moc"
851
852=== modified file 'src/service/keeper.h'
853--- src/service/keeper.h 2017-01-12 11:31:45 +0000
854+++ src/service/keeper.h 2017-01-12 11:31:45 +0000
855@@ -53,7 +53,7 @@
856 virtual ~Keeper();
857
858 keeper::Items get_backup_choices_var_dict_map(QDBusConnection bus, QDBusMessage const & msg);
859- keeper::Items get_restore_choices(QDBusConnection bus, QDBusMessage const & msg);
860+ keeper::Items get_restore_choices(QString const & storage, QDBusConnection bus, QDBusMessage const & msg);
861
862 QDBusUnixFileDescriptor StartBackup(QDBusConnection,
863 QDBusMessage const & message,
864@@ -64,8 +64,9 @@
865 QDBusMessage const & message);
866
867 void start_tasks(QStringList const & uuids,
868- QDBusConnection bus,
869- QDBusMessage const & msg);
870+ QString const & storage,
871+ QDBusConnection bus,
872+ QDBusMessage const & msg);
873
874 keeper::Items get_state() const;
875
876@@ -73,6 +74,9 @@
877
878 void invalidate_choices_cache();
879
880+ QStringList get_storage_accounts(QDBusConnection,
881+ QDBusMessage const & message);
882+
883 private:
884 QScopedPointer<KeeperPrivate> const d_ptr;
885 };
886
887=== modified file 'src/service/metadata-provider.h'
888--- src/service/metadata-provider.h 2017-01-12 11:31:45 +0000
889+++ src/service/metadata-provider.h 2017-01-12 11:31:45 +0000
890@@ -31,7 +31,7 @@
891 public:
892 virtual ~MetadataProvider() =0;
893 virtual QVector<Metadata> get_backups() const =0;
894- virtual void get_backups_async() =0;
895+ virtual void get_backups_async(QString const & storage) =0;
896
897 Q_SIGNALS:
898 void finished(keeper::Error error);
899
900=== modified file 'src/service/restore-choices.cpp'
901--- src/service/restore-choices.cpp 2017-01-12 11:31:45 +0000
902+++ src/service/restore-choices.cpp 2017-01-12 11:31:45 +0000
903@@ -42,9 +42,10 @@
904 }
905
906 void
907-RestoreChoices::get_backups_async()
908+RestoreChoices::get_backups_async(QString const & storage)
909 {
910 backups_.clear();
911+ storage_->set_storage(storage);
912 connections_.connect_future(
913 storage_->get_keeper_dirs(),
914 std::function<void(QVector<QString> const &)>{
915
916=== modified file 'src/service/restore-choices.h'
917--- src/service/restore-choices.h 2016-10-28 15:11:21 +0000
918+++ src/service/restore-choices.h 2017-01-12 11:31:45 +0000
919@@ -36,7 +36,7 @@
920 explicit RestoreChoices(QObject *parent = nullptr);
921 virtual ~RestoreChoices();
922 QVector<Metadata> get_backups() const override;
923- void get_backups_async() override;
924+ void get_backups_async(QString const & storage) override;
925
926 private:
927 QSharedPointer<StorageFrameworkClient> storage_;
928
929=== modified file 'src/service/task-manager.cpp'
930--- src/service/task-manager.cpp 2017-01-12 11:31:45 +0000
931+++ src/service/task-manager.cpp 2017-01-12 11:31:45 +0000
932@@ -41,18 +41,18 @@
933
934 ~TaskManagerPrivate() = default;
935
936- bool start_backup(QList<Metadata> const& tasks)
937+ bool start_backup(QList<Metadata> const& tasks, QString const & storage)
938 {
939 auto const now = QDateTime::currentDateTime();
940 backup_dir_name_ = now.toString("yyyy-MM-ddTHH-mm-ss");
941 active_manifest_.reset(new Manifest(storage_, backup_dir_name_), [](Manifest *m){m->deleteLater();});
942- return start_tasks(tasks, Mode::BACKUP);
943+ return start_tasks(tasks, storage, Mode::BACKUP);
944 }
945
946- bool start_restore(QList<Metadata> const& tasks)
947+ bool start_restore(QList<Metadata> const& tasks, QString const & storage)
948 {
949 qDebug() << "Starting restore...";
950- return start_tasks(tasks, Mode::RESTORE);
951+ return start_tasks(tasks, storage, Mode::RESTORE);
952 }
953
954 /***
955@@ -130,8 +130,9 @@
956
957 enum class Mode { IDLE, BACKUP, RESTORE };
958
959- bool start_tasks(QList<Metadata> const& tasks, Mode mode)
960+ bool start_tasks(QList<Metadata> const& tasks, QString const & storage, Mode mode)
961 {
962+ storage_->set_storage(storage);
963 bool success = true;
964
965 if (!remaining_tasks_.isEmpty())
966@@ -422,19 +423,19 @@
967 TaskManager::~TaskManager() = default;
968
969 bool
970-TaskManager::start_backup(QList<Metadata> const& tasks)
971+TaskManager::start_backup(QList<Metadata> const& tasks, QString const & storage)
972 {
973 Q_D(TaskManager);
974
975- return d->start_backup(tasks);
976+ return d->start_backup(tasks, storage);
977 }
978
979 bool
980-TaskManager::start_restore(QList<Metadata> const& tasks)
981+TaskManager::start_restore(QList<Metadata> const& tasks, QString const & storage)
982 {
983 Q_D(TaskManager);
984
985- return d->start_restore(tasks);
986+ return d->start_restore(tasks, storage);
987 }
988
989 keeper::Items TaskManager::get_state() const
990
991=== modified file 'src/service/task-manager.h'
992--- src/service/task-manager.h 2017-01-12 11:31:45 +0000
993+++ src/service/task-manager.h 2017-01-12 11:31:45 +0000
994@@ -50,9 +50,9 @@
995 NOTIFY state_changed)
996
997
998- bool start_backup(QList<Metadata> const& tasks);
999+ bool start_backup(QList<Metadata> const& tasks, QString const & storage);
1000
1001- bool start_restore(QList<Metadata> const& tasks);
1002+ bool start_restore(QList<Metadata> const& tasks, QString const & storage);
1003
1004 keeper::Items get_state() const;
1005
1006
1007=== modified file 'src/storage-framework/storage_framework_client.cpp'
1008--- src/storage-framework/storage_framework_client.cpp 2017-01-12 11:31:45 +0000
1009+++ src/storage-framework/storage_framework_client.cpp 2017-01-12 11:31:45 +0000
1010@@ -59,7 +59,31 @@
1011 }
1012 else // for now just pick the first one. FIXME
1013 {
1014- ret = choices.front();
1015+ for (auto& account : choices)
1016+ {
1017+ qDebug() << "Storage framework account found: [" << get_account_id(account) << "]";
1018+ }
1019+ if (storage_id_.isEmpty())
1020+ {
1021+ // FIXME use the default one, taking it from where it is defined
1022+ ret = choices.front();
1023+ }
1024+ else
1025+ {
1026+ for (auto& account : choices)
1027+ {
1028+ if (get_account_id(account) == storage_id_)
1029+ {
1030+ ret = account;
1031+ break;
1032+ }
1033+ }
1034+ if (!ret)
1035+ {
1036+ qWarning() << "Storage framework account [" << storage_id_ << "] was not found";
1037+ last_error_ = keeper::Error::ACCOUNT_NOT_FOUND;
1038+ }
1039+ }
1040 }
1041
1042 return ret;
1043@@ -70,15 +94,18 @@
1044 {
1045 sf::Root::SPtr ret;
1046
1047- qDebug() << "choosing from" << choices.size() << "roots";
1048- if (choices.empty())
1049- {
1050- qWarning() << "no storage-framework roots to pick from";
1051- last_error_ = keeper::Error::NO_REMOTE_ROOTS;
1052- }
1053- else // for now just pick the first one. FIXME
1054- {
1055- ret = choices.front();
1056+ if (last_error_ != keeper::Error::ACCOUNT_NOT_FOUND)
1057+ {
1058+ qDebug() << "choosing from" << choices.size() << "roots";
1059+ if (choices.empty())
1060+ {
1061+ qWarning() << "no storage-framework roots to pick from";
1062+ last_error_ = keeper::Error::NO_REMOTE_ROOTS;
1063+ }
1064+ else // for now just pick the first one. FIXME
1065+ {
1066+ ret = choices.front();
1067+ }
1068 }
1069
1070 return ret;
1071@@ -102,9 +129,19 @@
1072 auto account = choose(accounts);
1073 if (account)
1074 connection_helper_.connect_future(account->roots(), task);
1075+ else
1076+ {
1077+ QVector<sf::Root::SPtr> no_accounts;
1078+ task(no_accounts);
1079+ }
1080 });
1081 }
1082
1083+void StorageFrameworkClient::set_storage(QString const & storage)
1084+{
1085+ storage_id_ = storage;
1086+}
1087+
1088 QFuture<std::shared_ptr<Uploader>>
1089 StorageFrameworkClient::get_new_uploader(int64_t n_bytes, QString const & dir_name, QString const & file_name)
1090 {
1091@@ -296,6 +333,7 @@
1092 }
1093 else
1094 {
1095+ qDebug() << "No dirs were found";
1096 QVector<QString> res;
1097 QFutureInterface<decltype(res)> qfi(fi);
1098 qfi.reportResult(res);
1099@@ -311,6 +349,25 @@
1100 return last_error_;
1101 }
1102
1103+QFuture<QStringList>
1104+StorageFrameworkClient::get_accounts()
1105+{
1106+ QFutureInterface<QStringList> fi;
1107+ add_accounts_task([this, fi](QVector<sf::Account::SPtr> const& accounts)
1108+ {
1109+ QFutureInterface<QStringList> qfi(fi);
1110+ QStringList ret_accounts;
1111+ for (auto& account: accounts)
1112+ {
1113+ ret_accounts << get_account_id(account);
1114+ }
1115+ qfi.reportResult(ret_accounts);
1116+ qfi.reportFinished();
1117+ });
1118+
1119+ return fi.future();
1120+}
1121+
1122 QFuture<sf::Folder::SPtr>
1123 StorageFrameworkClient::get_keeper_folder(sf::Folder::SPtr const & root, QString const & dir_name, bool create_if_not_exists)
1124 {
1125@@ -477,3 +534,9 @@
1126 {
1127 last_error_ = keeper::Error::OK;
1128 }
1129+
1130+QString
1131+StorageFrameworkClient::get_account_id(unity::storage::qt::client::Account::SPtr const & account)
1132+{
1133+ return QStringLiteral("%1:%2").arg(account->owner_id()).arg(account->description());
1134+}
1135
1136=== modified file 'src/storage-framework/storage_framework_client.h'
1137--- src/storage-framework/storage_framework_client.h 2017-01-12 11:31:45 +0000
1138+++ src/storage-framework/storage_framework_client.h 2017-01-12 11:31:45 +0000
1139@@ -45,10 +45,12 @@
1140
1141 Q_DISABLE_COPY(StorageFrameworkClient)
1142
1143+ void set_storage(QString const & storage);
1144 QFuture<std::shared_ptr<Uploader>> get_new_uploader(int64_t n_bytes, QString const & dir_name, QString const & file_name);
1145 QFuture<std::shared_ptr<Downloader>> get_new_downloader(QString const & dir_name, QString const & file_name);
1146 QFuture<QVector<QString>> get_keeper_dirs();
1147 keeper::Error get_last_error() const;
1148+ QFuture<QStringList> get_accounts();
1149
1150 static QString const KEEPER_FOLDER;
1151 private:
1152@@ -66,7 +68,10 @@
1153
1154 void clear_last_error();
1155
1156+ static QString get_account_id(unity::storage::qt::client::Account::SPtr const & account);
1157+
1158 unity::storage::qt::client::Runtime::SPtr runtime_;
1159 ConnectionHelper connection_helper_;
1160+ QString storage_id_ = "";
1161 mutable keeper::Error last_error_ = keeper::Error::OK;
1162 };
1163
1164=== modified file 'tests/integration/helpers/helpers-test-failure.cpp'
1165--- tests/integration/helpers/helpers-test-failure.cpp 2017-01-12 11:31:45 +0000
1166+++ tests/integration/helpers/helpers-test-failure.cpp 2017-01-12 11:31:45 +0000
1167@@ -83,7 +83,7 @@
1168 QSignalSpy spy(properties_interface.data(),&DBusPropertiesInterface::PropertiesChanged);
1169
1170 // Now we know the music folder uuid, let's start the backup for it.
1171- QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid});
1172+ QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid}, "");
1173 ASSERT_TRUE(backup_reply.isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message());
1174
1175 // waits until all tasks are complete, recording PropertiesChanged signals
1176
1177=== modified file 'tests/integration/helpers/helpers-test.cc'
1178--- tests/integration/helpers/helpers-test.cc 2017-01-12 11:31:45 +0000
1179+++ tests/integration/helpers/helpers-test.cc 2017-01-12 11:31:45 +0000
1180@@ -128,7 +128,7 @@
1181 QSignalSpy spy(properties_interface.data(),&DBusPropertiesInterface::PropertiesChanged);
1182
1183 // Now we know the music folder uuid, let's start the backup for it.
1184- QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid, user_folder_uuid_2});
1185+ QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid, user_folder_uuid_2}, "");
1186 ASSERT_TRUE(backup_reply.isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message());
1187
1188 // waits until all tasks are complete, recording PropertiesChanged signals
1189@@ -145,7 +145,7 @@
1190 // finally check that we have a valid manifest file.
1191 EXPECT_TRUE(check_manifest_file(backup_items));
1192
1193- QDBusPendingReply<keeper::Items> restore_choices_reply = user_iface->call("GetRestoreChoices");
1194+ QDBusPendingReply<keeper::Items> restore_choices_reply = user_iface->call("GetRestoreChoices", "");
1195 restore_choices_reply.waitForFinished();
1196 EXPECT_TRUE(restore_choices_reply.isValid()) << qPrintable(choices.error().message());
1197
1198@@ -158,7 +158,7 @@
1199 EXPECT_EQ(user_folder_uuid, iter_restore.key());
1200
1201 // ask to restore that uuid
1202- QDBusPendingReply<void> restore_reply = user_iface->call("StartRestore", QStringList{iter_restore.key()});
1203+ QDBusPendingReply<void> restore_reply = user_iface->call("StartRestore", QStringList{iter_restore.key()}, "");
1204 restore_reply.waitForFinished();
1205 ASSERT_TRUE(restore_reply.isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message());
1206
1207@@ -168,7 +168,7 @@
1208
1209 // verify that the file that the fake restore helper creates is one of the ones in storage framework
1210 QString storage_framework_file_path;
1211- EXPECT_TRUE(StorageFrameworkLocalUtils::get_storage_frameowork_file_equal_to(TEST_RESTORE_FILE_PATH, storage_framework_file_path));
1212+ EXPECT_TRUE(StorageFrameworkLocalUtils::get_storage_framework_file_equal_to(TEST_RESTORE_FILE_PATH, storage_framework_file_path));
1213
1214 // Finally check that the storage framework file that matched is the right one
1215 // Keeper uses the display name plus .keeper extension for the files it creates
1216@@ -237,7 +237,7 @@
1217 QSignalSpy spy(properties_interface.data(),&DBusPropertiesInterface::PropertiesChanged);
1218
1219 // Now we know the music folder uuid, let's start the backup for it.
1220- QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid, user_folder_uuid_2});
1221+ QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{user_folder_uuid, user_folder_uuid_2}, "");
1222 ASSERT_TRUE(backup_reply.isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message());
1223
1224 EXPECT_TRUE(cancel_first_task_at_percentage(spy, 0.05, user_iface));
1225@@ -266,7 +266,7 @@
1226 ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message());
1227
1228 // Now we know the music folder uuid, let's start the backup for it.
1229- QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{"bad_uuid_1", "bad_uuid_2"});
1230+ QDBusReply<void> backup_reply = user_iface->call("StartBackup", QStringList{"bad_uuid_1", "bad_uuid_2"}, "");
1231
1232 ASSERT_FALSE(backup_reply.isValid());
1233
1234
1235=== modified file 'tests/integration/helpers/restore-test.cpp'
1236--- tests/integration/helpers/restore-test.cpp 2017-01-12 11:31:45 +0000
1237+++ tests/integration/helpers/restore-test.cpp 2017-01-12 11:31:45 +0000
1238@@ -92,7 +92,7 @@
1239 ASSERT_TRUE(user_iface->isValid()) << qPrintable(dbus_test_runner.sessionConnection().lastError().message());
1240
1241 // ask for a list of backup choices
1242- QDBusPendingReply<keeper::Items> choices_reply = user_iface->call("GetRestoreChoices");
1243+ QDBusPendingReply<keeper::Items> choices_reply = user_iface->call("GetRestoreChoices", "");
1244 choices_reply.waitForFinished();
1245 EXPECT_TRUE(choices_reply.isFinished());
1246 EXPECT_TRUE(choices_reply.isValid()) << qPrintable(choices_reply.error().message());
1247
1248=== modified file 'tests/utils/storage-framework-local.cpp'
1249--- tests/utils/storage-framework-local.cpp 2017-01-12 11:31:45 +0000
1250+++ tests/utils/storage-framework-local.cpp 2017-01-12 11:31:45 +0000
1251@@ -170,7 +170,7 @@
1252 : "";
1253 }
1254
1255-bool get_storage_frameowork_file_equal_to(QString const & file_path, QString & path)
1256+bool get_storage_framework_file_equal_to(QString const & file_path, QString & path)
1257 {
1258 auto const backups = get_storage_framework_files();
1259 for (auto const& backup : backups)
1260@@ -185,7 +185,7 @@
1261 return false;
1262 }
1263
1264-bool get_storage_frameowork_file_equal_in_size_to(QString const & file_path, QString & path)
1265+bool get_storage_framework_file_equal_in_size_to(QString const & file_path, QString & path)
1266 {
1267 auto const backups = get_storage_framework_files();
1268 for (auto const& backup : backups)
1269
1270=== modified file 'tests/utils/storage-framework-local.h'
1271--- tests/utils/storage-framework-local.h 2016-11-16 14:03:36 +0000
1272+++ tests/utils/storage-framework-local.h 2017-01-12 11:31:45 +0000
1273@@ -42,7 +42,7 @@
1274
1275 QString get_storage_framework_dir_name();
1276
1277- bool get_storage_frameowork_file_equal_to(QString const & file_path, QString & path);
1278+ bool get_storage_framework_file_equal_to(QString const & file_path, QString & path);
1279
1280- bool get_storage_frameowork_file_equal_in_size_to(QString const & file_path, QString & path);
1281+ bool get_storage_framework_file_equal_in_size_to(QString const & file_path, QString & path);
1282 }

Subscribers

People subscribed via source and target branches

to all changes: