Merge lp:~mterry/deja-dup/drop-u1 into lp:deja-dup/30

Proposed by Michael Terry
Status: Merged
Merge reported by: Michael Terry
Merged at revision: not available
Proposed branch: lp:~mterry/deja-dup/drop-u1
Merge into: lp:deja-dup/30
Diff against target: 559 lines (+36/-325)
11 files modified
data/org.gnome.DejaDup.gschema.xml.in (+0/-8)
debian/control (+2/-18)
deja-dup/MountOperationAssistant.vala (+1/-1)
deja-dup/deja-dup.appdata.xml.in (+1/-1)
deja-dup/widgets/ConfigLabelLocation.vala (+0/-2)
deja-dup/widgets/ConfigLocation.vala (+7/-5)
deja-dup/widgets/ConfigLocationU1.vala (+4/-3)
libdeja/BackendAuto.vala (+6/-15)
libdeja/BackendU1.vala (+3/-265)
libdeja/tests/runner.vala (+7/-7)
libdeja/tests/scripts/u1.test (+5/-0)
To merge this branch: bzr merge lp:~mterry/deja-dup/drop-u1
Reviewer Review Type Date Requested Status
Robert Bruce Park (community) Approve
Déjà Dup Developers Pending
Review via email: mp+213904@code.launchpad.net

Description of the change

Drop support for Ubuntu One.

Now that Ubuntu One is going away, we shouldn't act like it's available for users. This branch removes it from the UI, unless the user is already configured for it. Then, we continue to show it, but with a warning message in the preference dialog and an error when the user tries to back up or restore.

To post a comment you must log in.
lp:~mterry/deja-dup/drop-u1 updated
1536. By Michael Terry

Drop ubuntuone backend package

Revision history for this message
Robert Bruce Park (robru) wrote :

A surgical extraction of U1, indeed.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/org.gnome.DejaDup.gschema.xml.in'
--- data/org.gnome.DejaDup.gschema.xml.in 2013-10-15 04:36:06 +0000
+++ data/org.gnome.DejaDup.gschema.xml.in 2014-04-02 18:47:53 +0000
@@ -75,7 +75,6 @@
75 </key>75 </key>
76 <child name="rackspace" schema="org.gnome.DejaDup.Rackspace"/>76 <child name="rackspace" schema="org.gnome.DejaDup.Rackspace"/>
77 <child name="s3" schema="org.gnome.DejaDup.S3"/>77 <child name="s3" schema="org.gnome.DejaDup.S3"/>
78 <child name="u1" schema="org.gnome.DejaDup.U1"/>
79 <child name="file" schema="org.gnome.DejaDup.File"/>78 <child name="file" schema="org.gnome.DejaDup.File"/>
80 </schema>79 </schema>
81 <schema id="org.gnome.DejaDup.S3" path="/org/gnome/deja-dup/s3/">80 <schema id="org.gnome.DejaDup.S3" path="/org/gnome/deja-dup/s3/">
@@ -107,13 +106,6 @@
107 <_description>This is your username for the Rackspace Cloud Files service.</_description>106 <_description>This is your username for the Rackspace Cloud Files service.</_description>
108 </key>107 </key>
109 </schema>108 </schema>
110 <schema id="org.gnome.DejaDup.U1" path="/org/gnome/deja-dup/u1/">
111 <key name="folder" type="s">
112 <default>'/deja-dup/$HOSTNAME'</default>
113 <_summary>The Ubuntu One folder</_summary>
114 <_description>The folder name to store files in. If ‘$HOSTNAME’, it will default to a folder based on the name of the computer.</_description>
115 </key>
116 </schema>
117 <schema id="org.gnome.DejaDup.File" path="/org/gnome/deja-dup/file/">109 <schema id="org.gnome.DejaDup.File" path="/org/gnome/deja-dup/file/">
118 <key name="path" type="s">110 <key name="path" type="s">
119 <default>''</default>111 <default>''</default>
120112
=== modified file 'debian/control'
--- debian/control 2014-01-24 16:07:59 +0000
+++ debian/control 2014-04-02 18:47:53 +0000
@@ -36,15 +36,14 @@
36 policykit-1,36 policykit-1,
37Suggests: deja-dup-backend-cloudfiles,37Suggests: deja-dup-backend-cloudfiles,
38 deja-dup-backend-s3,38 deja-dup-backend-s3,
39 deja-dup-backend-ubuntuone,
40Description: Back up your files39Description: Back up your files
41 Déjà Dup is a simple backup tool. It hides the complexity of backing up the40 Déjà Dup is a simple backup tool. It hides the complexity of backing up the
42 Right Way (encrypted, off-site, and regular) and uses duplicity as the41 Right Way (encrypted, off-site, and regular) and uses duplicity as the
43 backend.42 backend.
44 .43 .
45 Features:44 Features:
46 * Support for local, remote, or cloud backup locations, such as Amazon S3,45 * Support for local, remote, or cloud backup locations, such as Amazon S3 and
47 Rackspace Cloud Files, and Ubuntu One46 Rackspace Cloud Files
48 * Securely encrypts and compresses your data47 * Securely encrypts and compresses your data
49 * Incrementally backs up, letting you restore from any particular backup48 * Incrementally backs up, letting you restore from any particular backup
50 * Schedules regular backups49 * Schedules regular backups
@@ -85,18 +84,3 @@
85 backend.84 backend.
86 .85 .
87 This package adds Amazon S3 support to Déjà Dup.86 This package adds Amazon S3 support to Déjà Dup.
88
89Package: deja-dup-backend-ubuntuone
90Architecture: all
91Depends: ${misc:Depends},
92 deja-dup,
93 python-httplib2,
94 python-oauthlib,
95 ubuntuone-client,
96 ubuntuone-control-panel,
97Description: Ubuntu One support for Déjà Dup
98 Déjà Dup is a simple backup tool. It hides the complexity of backing up the
99 Right Way (encrypted, off-site, and regular) and uses duplicity as the
100 backend.
101 .
102 This package adds Ubuntu One support to Déjà Dup.
10387
=== modified file 'deja-dup/MountOperationAssistant.vala'
--- deja-dup/MountOperationAssistant.vala 2013-10-18 18:36:51 +0000
+++ deja-dup/MountOperationAssistant.vala 2014-04-02 18:47:53 +0000
@@ -26,7 +26,7 @@
26 * 2) Or by driving the authentication themselves in some secret way. If so,26 * 2) Or by driving the authentication themselves in some secret way. If so,
27 * they will ask for a button to be shown to start the authentication.27 * they will ask for a button to be shown to start the authentication.
28 * When they are done, they will set the 'go_forward' property to true.28 * When they are done, they will set the 'go_forward' property to true.
29 * This is used by the U1 backend.29 * This was used by the U1 backend.
30 */30 */
3131
32public class MountOperationAssistant : MountOperation32public class MountOperationAssistant : MountOperation
3333
=== modified file 'deja-dup/deja-dup.appdata.xml.in'
--- deja-dup/deja-dup.appdata.xml.in 2013-11-08 03:25:36 +0000
+++ deja-dup/deja-dup.appdata.xml.in 2014-04-02 18:47:53 +0000
@@ -7,7 +7,7 @@
7 <description>7 <description>
8 <_p>Déjà Dup is a simple backup tool. It hides the complexity of backing up the Right Way (encrypted, off-site, and regular) and uses duplicity as the backend.</_p>8 <_p>Déjà Dup is a simple backup tool. It hides the complexity of backing up the Right Way (encrypted, off-site, and regular) and uses duplicity as the backend.</_p>
9 <ul>9 <ul>
10 <_li>Support for local, remote, or cloud backup locations, such as Amazon S3, Rackspace Cloud Files, and Ubuntu One</_li>10 <_li>Support for local, remote, or cloud backup locations, such as Amazon S3 and Rackspace Cloud Files</_li>
11 <_li>Securely encrypts and compresses your data</_li>11 <_li>Securely encrypts and compresses your data</_li>
12 <_li>Incrementally backs up, letting you restore from any particular backup</_li>12 <_li>Incrementally backs up, letting you restore from any particular backup</_li>
13 <_li>Schedules regular backups</_li>13 <_li>Schedules regular backups</_li>
1414
=== modified file 'deja-dup/widgets/ConfigLabelLocation.vala'
--- deja-dup/widgets/ConfigLabelLocation.vala 2013-01-27 20:30:52 +0000
+++ deja-dup/widgets/ConfigLabelLocation.vala 2014-04-02 18:47:53 +0000
@@ -26,7 +26,6 @@
26 Gtk.Image img;26 Gtk.Image img;
27 FilteredSettings file_root;27 FilteredSettings file_root;
28 FilteredSettings s3_root;28 FilteredSettings s3_root;
29 FilteredSettings u1_root;
30 FilteredSettings rackspace_root;29 FilteredSettings rackspace_root;
3130
32 public ConfigLabelLocation()31 public ConfigLabelLocation()
@@ -40,7 +39,6 @@
40 watch_key(BACKEND_KEY);39 watch_key(BACKEND_KEY);
41 watch_key(null, (file_root = DejaDup.get_settings(FILE_ROOT)));40 watch_key(null, (file_root = DejaDup.get_settings(FILE_ROOT)));
42 watch_key(null, (s3_root = DejaDup.get_settings(S3_ROOT)));41 watch_key(null, (s3_root = DejaDup.get_settings(S3_ROOT)));
43 watch_key(null, (u1_root = DejaDup.get_settings(U1_ROOT)));
44 watch_key(null, (rackspace_root = DejaDup.get_settings(RACKSPACE_ROOT)));42 watch_key(null, (rackspace_root = DejaDup.get_settings(RACKSPACE_ROOT)));
45 set_from_config.begin();43 set_from_config.begin();
46 }44 }
4745
=== modified file 'deja-dup/widgets/ConfigLocation.vala'
--- deja-dup/widgets/ConfigLocation.vala 2013-10-19 17:43:57 +0000
+++ deja-dup/widgets/ConfigLocation.vala 2014-04-02 18:47:53 +0000
@@ -179,7 +179,9 @@
179 }179 }
180180
181 void insert_u1() {181 void insert_u1() {
182 insert_cloud_if_available("u1", BackendU1.get_checker(),182 // No longer functional.
183 // Only shown if user already had it configured, for migration purposes.
184 insert_cloud_if_available("u1", null,
183 new ThemedIcon.from_names({"ubuntuone",185 new ThemedIcon.from_names({"ubuntuone",
184 "ubuntuone-installer",186 "ubuntuone-installer",
185 "deja-dup-cloud"}),187 "deja-dup-cloud"}),
@@ -196,18 +198,18 @@
196 ref index_rackspace, insert_rackspace);198 ref index_rackspace, insert_rackspace);
197 }199 }
198200
199 void insert_cloud_if_available(string id, Checker checker,201 void insert_cloud_if_available(string id, Checker? checker,
200 Icon icon, string name,202 Icon icon, string name,
201 Gtk.Widget w, ref int index,203 Gtk.Widget? w, ref int index,
202 CloudCallback cb)204 CloudCallback cb)
203 {205 {
204 var backend = Backend.get_default_type();206 var backend = Backend.get_default_type();
205 if (backend == id || (checker.complete && checker.available)) {207 if (backend == id || (checker != null && checker.complete && checker.available)) {
206 index = add_entry(icon, name, Group.CLOUD, w);208 index = add_entry(icon, name, Group.CLOUD, w);
207 if (index_cloud_sep == -2)209 if (index_cloud_sep == -2)
208 index_cloud_sep = add_separator(Group.CLOUD_SEP);210 index_cloud_sep = add_separator(Group.CLOUD_SEP);
209 }211 }
210 else if (!checker.complete) {212 else if (checker != null && !checker.complete) {
211 // Call ourselves when we've got enough information. Also make sure to213 // Call ourselves when we've got enough information. Also make sure to
212 // set from config again, in case in a previous set_from_config, we214 // set from config again, in case in a previous set_from_config, we
213 // weren't available in the combo yet.215 // weren't available in the combo yet.
214216
=== modified file 'deja-dup/widgets/ConfigLocationU1.vala'
--- deja-dup/widgets/ConfigLocationU1.vala 2012-03-17 04:02:46 +0000
+++ deja-dup/widgets/ConfigLocationU1.vala 2014-04-02 18:47:53 +0000
@@ -28,9 +28,10 @@
28 }28 }
2929
30 construct {30 construct {
31 var entry = new ConfigFolder(DejaDup.U1_FOLDER_KEY, DejaDup.U1_ROOT);31 var label = new Gtk.Label("");
32 entry.set_accessible_name("U1Folder");32 label.set_markup("<b><big>%s</big></b>".printf(_("Ubuntu One has shut down. Please choose another storage location.")));
33 add_widget(_("_Folder"), entry);33 label.margin_top = 20;
34 add_wide_widget(label);
34 }35 }
35}36}
3637
3738
=== modified file 'libdeja/BackendAuto.vala'
--- libdeja/BackendAuto.vala 2012-03-21 03:01:36 +0000
+++ libdeja/BackendAuto.vala 2014-04-02 18:47:53 +0000
@@ -50,7 +50,6 @@
5050
51 static bool started = false;51 static bool started = false;
52 static bool done = false;52 static bool done = false;
53 Checker u1checker;
54 Checker s3checker;53 Checker s3checker;
55 construct {54 construct {
56 if (!started) {55 if (!started) {
@@ -59,10 +58,7 @@
59 started = true;58 started = true;
60 ref(); // Give us time to finish59 ref(); // Give us time to finish
6160
62 // List is (in order): u1, s3, file61 // List is (in order): s3, file
63 u1checker = BackendU1.get_checker();
64 u1checker.notify["complete"].connect(examine_checkers);
65
66 s3checker = BackendS3.get_checker();62 s3checker = BackendS3.get_checker();
67 s3checker.notify["complete"].connect(examine_checkers);63 s3checker.notify["complete"].connect(examine_checkers);
6864
@@ -75,16 +71,11 @@
75 if (done)71 if (done)
76 return;72 return;
7773
78 if (u1checker.complete) {74 if (s3checker.complete) {
79 if (u1checker.available) {75 if (s3checker.available)
80 finish("u1");76 finish("s3");
81 }77 else
82 else if (s3checker.complete) {78 finish("file");
83 if (s3checker.available)
84 finish("s3");
85 else
86 finish("file");
87 }
88 }79 }
89 }80 }
9081
9182
=== modified file 'libdeja/BackendU1.vala'
--- libdeja/BackendU1.vala 2012-11-05 15:17:28 +0000
+++ libdeja/BackendU1.vala 2014-04-02 18:47:53 +0000
@@ -21,295 +21,33 @@
2121
22namespace DejaDup {22namespace DejaDup {
2323
24public const string U1_ROOT = "U1";
25public const string U1_FOLDER_KEY = "folder";
26
27class Listener : Object
28{
29 public delegate void Handler(string name, Variant args);
30 public DBusProxy proxy {get; construct;}
31 public string method {get; construct;}
32 public Variant args {get; construct;}
33 public unowned Handler handler {get; set;}
34
35 public Listener(DBusProxy proxy, string method, Variant? args, Handler handler)
36 {
37 Object(proxy: proxy, method: method, args: args);
38 this.handler = handler;
39 }
40
41 MainLoop loop;
42 construct {
43 loop = new MainLoop(null, false);
44 }
45
46 public void run()
47 {
48 Idle.add(() => {
49 call_but_quit_on_fail.begin();
50 return false;
51 });
52 proxy.g_signal.connect(handle_dbus_signal);
53 loop.run();
54 proxy.g_signal.disconnect(handle_dbus_signal);
55 }
56
57 async void call_but_quit_on_fail()
58 {
59 try {
60 yield proxy.call(method, args, DBusCallFlags.NONE, -1, null);
61 }
62 catch (Error e) {
63 warning("%s\n", e.message);
64 loop.quit();
65 }
66 }
67
68 void handle_dbus_signal(DBusProxy obj, string? sender, string name, Variant args)
69 {
70 // Stop on first signal
71 handler(name, args);
72 loop.quit();
73 }
74}
75
76class U1Checker : Checker
77{
78 PythonChecker pyu1;
79 construct {
80 try {
81 var proxy = BackendU1.get_creds_proxy();
82 if (proxy.get_name_owner() == null) {
83 available = false;
84 complete = true;
85 }
86 }
87 catch (Error e) {
88 warning("%s\n", e.message);
89 available = false;
90 complete = true;
91 }
92
93 if (!complete) {
94 // A bit of abstraction leakage here; we have to keep these imports in
95 // line with what duplicity uses. Maybe we should add to duplicity a way
96 // to ask 'can I use this backend?'
97 pyu1 = PythonChecker.get_checker("oauthlib, httplib2");
98 if (pyu1.complete) {
99 available = pyu1.available;
100 complete = pyu1.complete;
101 }
102 else {
103 pyu1.notify["complete"].connect(() => {
104 available = pyu1.available;
105 complete = pyu1.complete;
106 pyu1 = null;
107 });
108 }
109 }
110 }
111}
112
113public class BackendU1 : Backend24public class BackendU1 : Backend
114{25{
115 ulong button_handler = 0;
116
117 static Checker checker_instance = null;
118 public static Checker get_checker()
119 {
120 if (checker_instance == null)
121 checker_instance = new U1Checker();
122 return checker_instance;
123 }
124
125 public override Backend clone() {26 public override Backend clone() {
126 return new BackendU1();27 return new BackendU1();
127 }28 }
12829
129 ~BackendU1()
130 {
131 if (button_handler > 0) {
132 mount_op.disconnect(button_handler);
133 button_handler = 0;
134 }
135 }
136
137 public override bool is_native() {30 public override bool is_native() {
138 return false;31 return false;
139 }32 }
14033
141 public override bool space_can_be_infinite() {
142 return false;
143 }
144
145 public override Icon? get_icon() {34 public override Icon? get_icon() {
146 return new ThemedIcon.from_names({"ubuntuone", "ubuntuone-installer", "deja-dup-cloud"});35 return new ThemedIcon.from_names({"ubuntuone", "ubuntuone-installer", "deja-dup-cloud"});
147 }36 }
14837
149 public override async bool is_ready(out string when) {
150 when = _("Backup will begin when a network connection becomes available.");
151 return yield Network.get().can_reach ("https://one.ubuntu.com/");
152 }
153
154 public override string get_location(ref bool as_root)38 public override string get_location(ref bool as_root)
155 {39 {
156 // The UI backend for duplicity needs to talk to our session dbus, but it40 return "";
157 // can't as root.
158 as_root = false;
159
160 var settings = get_settings(U1_ROOT);
161 var folder = get_folder_key(settings, U1_FOLDER_KEY);
162 return "u1+http://%s".printf(folder);
163 }41 }
16442
165 public override string get_location_pretty()43 public override string get_location_pretty()
166 {44 {
167 var settings = get_settings(U1_ROOT);45 return _("Ubuntu One");
168 var folder = get_folder_key(settings, U1_FOLDER_KEY);
169 if (folder == "")
170 return _("Ubuntu One");
171 else
172 // Translators: %s is a folder.
173 return _("%s on Ubuntu One").printf(folder);
174 }
175
176 public override async uint64 get_space(bool free = true)
177 {
178 DBusProxy obj = null;
179 try {
180 obj = get_prefs_proxy();
181 }
182 catch (Error e) {
183 warning("%s\n", e.message);
184 return INFINITE_SPACE;
185 }
186
187 if (obj.get_name_owner() == null)
188 return INFINITE_SPACE;
189
190 uint64 total = INFINITE_SPACE;
191 uint64 used = 0;
192 var listener = new Listener(obj, "account_info", null, (name, args) => {
193 if (name == "AccountInfoReady") {
194 VariantIter iter;
195 args.get("(a{ss})", out iter);
196 string key, val;
197 while (iter.next("{ss}", out key, out val)) {
198 if (key == "quota_total")
199 total = uint64.parse(val);
200 else if (key == "quota_used")
201 used = uint64.parse(val);
202 }
203 }
204 });
205 listener.run();
206
207 if (free)
208 return (total > used) ? (total - used) : 0;
209 else
210 return total;
211 }46 }
21247
213 public override async void get_envp() throws Error48 public override async void get_envp() throws Error
214 {49 {
215 var obj = get_creds_proxy();50 throw new BackupError.BAD_CONFIG(_("Ubuntu One has shut down. Please choose another storage location."));
216 if (obj.get_name_owner() == null) {
217 ask_password();
218 return;
219 }
220
221 var found = false;
222 var envp = new List<string>();
223 var listener = new Listener(obj, "find_credentials", null, (name, args) => {
224 if (name == "CredentialsFound") {
225 VariantIter iter;
226 args.get("(a{ss})", out iter);
227 string key, val;
228 string consumer_key = null, consumer_secret = null, token = null, token_secret = null;
229 while (iter.next("{ss}", out key, out val)) {
230 if (key == "consumer_key")
231 consumer_key = val;
232 else if (key == "consumer_secret")
233 consumer_secret = val;
234 else if (key == "token")
235 token = val;
236 else if (key == "token_secret")
237 token_secret = val;
238 }
239 if (consumer_key != null && consumer_secret != null && token != null && token_secret != null) {
240 envp.append("FTP_PASSWORD=%s:%s:%s:%s".printf(consumer_key, consumer_secret, token, token_secret));
241 found = true;
242 }
243 }
244 });
245 listener.run();
246
247 if (found)
248 envp_ready(true, envp);
249 else
250 ask_password();
251 }
252
253 void button_clicked()
254 {
255 sign_in.begin();
256 }
257
258 void ask_password() {
259 mount_op.set("label_title", _("Connect to Ubuntu One"));
260 mount_op.set("label_button", _("Sign into Ubuntu One…"));
261 if (button_handler == 0)
262 button_handler = Signal.connect_swapped(mount_op, "button-clicked",
263 (Callback)button_clicked, this);
264 mount_op.ask_password("", "", "", 0);
265 }
266
267 async void sign_in()
268 {
269 try {
270 var obj = get_creds_proxy();
271 if (obj.get_name_owner() == null) {
272 envp_ready(false, null);
273 return;
274 }
275
276 var listener = new Listener(obj, "login", new Variant("(a{ss})", null),
277 (name, args) => {
278 if (name == "CredentialsFound") {
279 mount_op.set("go_forward", true);
280 envp_ready(true, null);
281 }
282 });
283 listener.run();
284 }
285 catch (Error e) {
286 warning("%s\n", e.message);
287 envp_ready(false, null);
288 }
289 }
290
291 public static DBusProxy get_creds_proxy() throws Error
292 {
293 DBusProxy creds_proxy;
294 creds_proxy = new DBusProxy.for_bus_sync(BusType.SESSION,
295 DBusProxyFlags.NONE, null,
296 "com.ubuntuone.Credentials",
297 "/credentials",
298 "com.ubuntuone.CredentialsManagement",
299 null);
300 return creds_proxy;
301 }
302
303 public static DBusProxy get_prefs_proxy() throws Error
304 {
305 DBusProxy prefs_proxy;
306 prefs_proxy = new DBusProxy.for_bus_sync(BusType.SESSION,
307 DBusProxyFlags.NONE, null,
308 "com.ubuntuone.controlpanel",
309 "/preferences",
310 "com.ubuntuone.controlpanel.Preferences",
311 null);
312 return prefs_proxy;
313 }51 }
314}52}
31553
31654
=== modified file 'libdeja/tests/runner.vala'
--- libdeja/tests/runner.vala 2013-10-01 02:02:26 +0000
+++ libdeja/tests/runner.vala 2014-04-02 18:47:53 +0000
@@ -418,13 +418,6 @@
418 if (keyfile.has_key(group, "RestoreDate"))418 if (keyfile.has_key(group, "RestoreDate"))
419 br.restore_date = keyfile.get_string(group, "RestoreDate");419 br.restore_date = keyfile.get_string(group, "RestoreDate");
420420
421 var type = keyfile.get_string(group, "Type");
422 if (type == "backup")
423 br.op = new DejaDup.OperationBackup();
424 else if (type == "restore")
425 br.op = new DejaDup.OperationRestore(restoredir, br.restore_date, br.restore_files);
426 else
427 assert_not_reached();
428 if (keyfile.has_key(group, "Success"))421 if (keyfile.has_key(group, "Success"))
429 br.success = keyfile.get_boolean(group, "Success");422 br.success = keyfile.get_boolean(group, "Success");
430 if (keyfile.has_key(group, "Canceled"))423 if (keyfile.has_key(group, "Canceled"))
@@ -465,6 +458,13 @@
465 }458 }
466 }459 }
467 }460 }
461 var type = keyfile.get_string(group, "Type");
462 if (type == "backup")
463 br.op = new DejaDup.OperationBackup();
464 else if (type == "restore")
465 br.op = new DejaDup.OperationRestore(restoredir, br.restore_date, br.restore_files);
466 else
467 assert_not_reached();
468}468}
469469
470string get_string_field(KeyFile keyfile, string group, string key) throws Error470string get_string_field(KeyFile keyfile, string group, string key) throws Error
471471
=== added file 'libdeja/tests/scripts/u1.test'
--- libdeja/tests/scripts/u1.test 1970-01-01 00:00:00 +0000
+++ libdeja/tests/scripts/u1.test 2014-04-02 18:47:53 +0000
@@ -0,0 +1,5 @@
1[Operation]
2Settings=backend='u1';
3Type=backup
4Success=false
5Error=Ubuntu One has shut down. Please choose another storage location.

Subscribers

People subscribed via source and target branches