mirror of
				https://github.com/mail-in-a-box/mailinabox.git
				synced 2025-10-31 19:00:54 +00:00 
			
		
		
		
	Implement Backblaze for Backup (#1812)
* Installing b2sdk for b2 support * Added Duplicity PPA so the most recent version is used * Implemented list_target_files for b2 * Implemented b2 in frontend * removed python2 boto package
This commit is contained in:
		
							parent
							
								
									82229ce04b
								
							
						
					
					
						commit
						8664afa997
					
				| @ -456,6 +456,23 @@ def list_target_files(config): | ||||
| 			raise ValueError(e.reason) | ||||
| 
 | ||||
| 		return [(key.name[len(path):], key.size) for key in bucket.list(prefix=path)] | ||||
| 	elif target.scheme == 'b2': | ||||
| 		from b2sdk.v1 import InMemoryAccountInfo, B2Api | ||||
| 		from b2sdk.v1.exception import NonExistentBucket | ||||
| 		info = InMemoryAccountInfo() | ||||
| 		b2_api = B2Api(info) | ||||
| 		 | ||||
| 		# Extract information from target | ||||
| 		b2_application_keyid = target.netloc[:target.netloc.index(':')] | ||||
| 		b2_application_key = target.netloc[target.netloc.index(':')+1:target.netloc.index('@')] | ||||
| 		b2_bucket = target.netloc[target.netloc.index('@')+1:] | ||||
| 
 | ||||
| 		try: | ||||
| 			b2_api.authorize_account("production", b2_application_keyid, b2_application_key) | ||||
| 			bucket = b2_api.get_bucket_by_name(b2_bucket) | ||||
| 		except NonExistentBucket as e: | ||||
| 			raise ValueError("B2 Bucket does not exist. Please double check your information!") | ||||
| 		return [(key.file_name, key.size) for key, _ in bucket.ls()] | ||||
| 
 | ||||
| 	else: | ||||
| 		raise ValueError(config["target"]) | ||||
|  | ||||
| @ -18,6 +18,7 @@ | ||||
|         <option value="local">{{hostname}}</option> | ||||
|         <option value="rsync">rsync</option> | ||||
|         <option value="s3">Amazon S3</option> | ||||
|         <option value="b2">Backblaze B2</option> | ||||
|       </select> | ||||
|     </div> | ||||
|   </div> | ||||
| @ -111,6 +112,31 @@ | ||||
|       <input type="text" class="form-control" rows="1" id="backup-target-pass"> | ||||
|     </div> | ||||
|   </div> | ||||
|   <!-- Backblaze --> | ||||
|   <div class="form-group backup-target-b2"> | ||||
|       <div class="col-sm-10 col-sm-offset-2"> | ||||
|         <p>Backups are stored in a <a href="https://www.backblaze.com/" target="_blank" rel="noreferrer">Backblaze</a> B2 bucket. You must have a Backblaze account already.</p> | ||||
|         <p>You MUST manually copy the encryption password from <tt class="backup-encpassword-file"></tt> to a safe and secure location. You will need this file to decrypt backup files. It is NOT stored in your Backblaze B2 bucket.</p> | ||||
|       </div> | ||||
|   </div> | ||||
|   <div class="form-group backup-target-b2"> | ||||
|       <label for="backup-target-b2-user" class="col-sm-2 control-label">B2 Application KeyID</label> | ||||
|       <div class="col-sm-8"> | ||||
|         <input type="text" class="form-control" rows="1" id="backup-target-b2-user"> | ||||
|       </div> | ||||
|   </div> | ||||
|   <div class="form-group backup-target-b2"> | ||||
|       <label for="backup-target-b2-pass" class="col-sm-2 control-label">B2 Application Key</label> | ||||
|       <div class="col-sm-8"> | ||||
|         <input type="text" class="form-control" rows="1" id="backup-target-b2-pass"> | ||||
|       </div> | ||||
|   </div> | ||||
|   <div class="form-group backup-target-b2"> | ||||
|       <label for="backup-target-b2-bucket" class="col-sm-2 control-label">B2 Bucket</label> | ||||
|       <div class="col-sm-8"> | ||||
|         <input type="text" class="form-control" rows="1" id="backup-target-b2-bucket"> | ||||
|       </div> | ||||
|   </div> | ||||
|   <!-- Common --> | ||||
|   <div class="form-group backup-target-local backup-target-rsync backup-target-s3"> | ||||
|     <label for="min-age" class="col-sm-2 control-label">Retention Days:</label> | ||||
| @ -144,7 +170,7 @@ | ||||
| 
 | ||||
| function toggle_form() { | ||||
|   var target_type = $("#backup-target-type").val(); | ||||
|   $(".backup-target-local, .backup-target-rsync, .backup-target-s3").hide(); | ||||
|   $(".backup-target-local, .backup-target-rsync, .backup-target-s3, .backup-target-b2").hide(); | ||||
|   $(".backup-target-" + target_type).show(); | ||||
| 
 | ||||
|   init_inputs(target_type); | ||||
| @ -215,7 +241,7 @@ function show_system_backup() { | ||||
| } | ||||
| 
 | ||||
| function show_custom_backup() { | ||||
|     $(".backup-target-local, .backup-target-rsync, .backup-target-s3").hide(); | ||||
|     $(".backup-target-local, .backup-target-rsync, .backup-target-s3, .backup-target-b2").hide(); | ||||
|     api( | ||||
|       "/system/backup/config", | ||||
|       "GET", | ||||
| @ -245,6 +271,15 @@ function show_custom_backup() { | ||||
|           var host = hostpath.shift(); | ||||
|           $("#backup-target-s3-host").val(host); | ||||
|           $("#backup-target-s3-path").val(hostpath.join('/')); | ||||
|         } else if (r.target.substring(0, 5) == "b2://") { | ||||
|           $("#backup-target-type").val("b2"); | ||||
|           var targetPath = r.target.substring(5); | ||||
|           var b2_application_keyid = targetPath.split(':')[0]; | ||||
|           var b2_applicationkey = targetPath.split(':')[1].split('@')[0]; | ||||
|           var b2_bucket = targetPath.split('@')[1]; | ||||
|           $("#backup-target-b2-user").val(b2_application_keyid); | ||||
|           $("#backup-target-b2-pass").val(b2_applicationkey); | ||||
|           $("#backup-target-b2-bucket").val(b2_bucket); | ||||
|         } | ||||
|         toggle_form() | ||||
|       }) | ||||
| @ -264,6 +299,11 @@ function set_custom_backup() { | ||||
|     target = "rsync://" + $("#backup-target-rsync-user").val() + "@" + $("#backup-target-rsync-host").val() | ||||
|                                                                 + "/" + $("#backup-target-rsync-path").val(); | ||||
|     target_user = ''; | ||||
|   } else if (target_type == "b2") { | ||||
|     target = 'b2://' + $('#backup-target-b2-user').val() + ':' + $('#backup-target-b2-pass').val() | ||||
|         + '@' + $('#backup-target-b2-bucket').val() | ||||
|     target_user = ''; | ||||
|     target_pass = ''; | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
| @ -303,4 +343,4 @@ function init_inputs(target_type) { | ||||
|     set_host($('#backup-target-s3-host-select').val()); | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| </script> | ||||
| @ -18,11 +18,7 @@ while [ -d /usr/local/lib/python3.4/dist-packages/acme ]; do | ||||
| 	pip3 uninstall -y acme; | ||||
| done | ||||
| 
 | ||||
| # duplicity is used to make backups of user data. It uses boto | ||||
| # (via Python 2) to do backups to AWS S3. boto from the Ubuntu | ||||
| # package manager is too out-of-date -- it doesn't support the newer | ||||
| # S3 api used in some regions, which breaks backups to those regions. | ||||
| # See #627, #653. | ||||
| # duplicity is used to make backups of user data. | ||||
| # | ||||
| # virtualenv is used to isolate the Python 3 packages we | ||||
| # install via pip from the system-installed packages. | ||||
| @ -30,7 +26,11 @@ done | ||||
| # certbot installs EFF's certbot which we use to | ||||
| # provision free TLS certificates. | ||||
| apt_install duplicity python-pip virtualenv certbot | ||||
| hide_output pip2 install --upgrade boto | ||||
| 
 | ||||
| # b2sdk is used for backblaze backups. | ||||
| # boto is used for amazon aws backups. | ||||
| # Both are installed outside the pipenv, so they can be used by duplicity | ||||
| hide_output pip3 install --upgrade b2sdk boto | ||||
| 
 | ||||
| # Create a virtualenv for the installation of Python 3 packages | ||||
| # used by the management daemon. | ||||
| @ -50,8 +50,8 @@ hide_output $venv/bin/pip install --upgrade pip | ||||
| hide_output $venv/bin/pip install --upgrade \ | ||||
| 	rtyaml "email_validator>=1.0.0" "exclusiveprocess" \ | ||||
| 	flask dnspython python-dateutil \ | ||||
|     qrcode[pil] pyotp \ | ||||
| 	"idna>=2.0.0" "cryptography==2.2.2" boto psutil postfix-mta-sts-resolver | ||||
|   qrcode[pil] pyotp \ | ||||
| 	"idna>=2.0.0" "cryptography==2.2.2" boto psutil postfix-mta-sts-resolver b2sdk | ||||
| 
 | ||||
| # CONFIGURATION | ||||
| 
 | ||||
|  | ||||
| @ -93,6 +93,9 @@ hide_output add-apt-repository -y universe | ||||
| # Install the certbot PPA. | ||||
| hide_output add-apt-repository -y ppa:certbot/certbot | ||||
| 
 | ||||
| # Install the duplicity PPA. | ||||
| hide_output add-apt-repository -y ppa:duplicity-team/duplicity-release-git | ||||
| 
 | ||||
| # ### Update Packages | ||||
| 
 | ||||
| # Update system packages to make sure we have the latest upstream versions | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user