def get_seed(): current_app.logger.info("Fetch seed from MineBD.") # Get wallet seed from MineBD. seed = None mbdata, mb_status_code = get_from_minebd('siawalletseed') if mb_status_code == 200: seed = mbdata["message"] return seed
def api_status(): # Doc: https://bitbucket.org/mineboxgmbh/minebox-client-tools/src/master/doc/mb-ui-gateway-api.md#markdown-header-get-status username = check_login() outdata = {} if username: outdata["logged_in"] = True outdata["user"] = username else: outdata["logged_in"] = False outdata["user"] = None mbdata, mb_status_code = get_from_minebd('status') if mb_status_code == 200: outdata["minebd_running"] = True outdata["minebd_encrypted"] = mbdata["hasEncryptionKey"] outdata["minebd_storage_mounted"] = ismount(MINEBD_STORAGE_PATH) outdata["restore_running"] = mbdata["restoreRunning"] outdata["restore_progress"] = mbdata["completedRestorePercent"] else: outdata["minebd_running"] = False outdata["minebd_encrypted"] = None outdata["minebd_storage_mounted"] = False outdata["restore_running"] = False outdata["restore_progress"] = None hasusers = False for user in pwd.getpwall(): if user.pw_uid >= 1000 and user.pw_uid < 65500 and user.pw_name != "sia": hasusers = True outdata["users_created"] = hasusers if 'DEMO' in environ: outdata["backup_type"] = "sia_demo" else: outdata["backup_type"] = "sia" consdata, cons_status_code = get_from_sia('consensus') if cons_status_code == 200: outdata["sia_daemon_running"] = True outdata["consensus_height"] = consdata["height"] outdata["consensus_synced"] = consdata["synced"] else: outdata["sia_daemon_running"] = False outdata["consensus_height"] = None outdata["consensus_synced"] = None walletdata, wallet_status_code = get_from_sia('wallet') if username and wallet_status_code == 200: outdata["wallet_unlocked"] = walletdata["unlocked"] outdata["wallet_encrypted"] = walletdata["encrypted"] outdata["wallet_confirmed_balance_sc"] = int(walletdata["confirmedsiacoinbalance"]) / H_PER_SC outdata["wallet_unconfirmed_delta_sc"] = (int(walletdata["unconfirmedincomingsiacoins"]) - int(walletdata["unconfirmedoutgoingsiacoins"])) / H_PER_SC else: outdata["wallet_unlocked"] = None outdata["wallet_encrypted"] = None outdata["wallet_confirmed_balance_sc"] = None outdata["wallet_unconfirmed_delta_sc"] = None return jsonify(outdata), 200
def check_backup_prerequisites(): # Check if prerequisites are met to make backups. success, errmsg = check_sia_sync() if not success: return False, errmsg siadata, sia_status_code = get_from_sia("renter/contracts") if sia_status_code >= 400: return False, siadata["message"] if not siadata["contracts"]: return False, "No Sia renter contracts, so uploading is not possible." mbdata, mb_status_code = get_from_minebd('status') if mb_status_code >= 400: return False, mbdata["message"] if mbdata["restoreRunning"] and mbdata["completedRestorePercent"] < 100: return False, "MineBD is running an incomplete restore, so creating a backup is not possible." # Potentially check things other than sia. return True, ""
def api_key_put(): # Doc: https://bitbucket.org/mineboxgmbh/minebox-client-tools/src/master/doc/mb-ui-gateway-api.md#markdown-header-put-key mbdata, mb_status_code = get_from_minebd('status') if mb_status_code == 200: if mbdata["hasEncryptionKey"]: return jsonify(message="File system is already encrypted, cannot set key."), 400 # MineBD is running but encryption is not yet set up, we can actually set a key! if len(request.data): retcode = subprocess.call([SUDO, MBKEY_CMD, "set", request.data]) if retcode == 0: return jsonify(message="Key set successfully"), 200 else: return jsonify(message="Setting key failed."), 500 else: return jsonify(message="No useful key handed over."), 400 else: return jsonify(message="The Minebox storage is not running, please reboot the box or call support!"), 503
def api_status(): # Doc: https://bitbucket.org/mineboxgmbh/minebox-client-tools/src/master/doc/mb-ui-gateway-api.md#markdown-header-get-status username = check_login() outdata = {} outdata["hostname"] = uname()[1] if username: outdata["logged_in"] = True outdata["user"] = username else: outdata["logged_in"] = False outdata["user"] = None mbdata, mb_status_code = get_from_minebd('status') if mb_status_code == 200: outdata["minebd_running"] = True outdata["minebd_encrypted"] = mbdata["hasEncryptionKey"] outdata["minebd_storage_mounted"] = ismount(MINEBD_STORAGE_PATH) ST_RDONLY = 1 # In Python >= 3.2, we could use os.ST_RDONLY directly instead. outdata["minebd_storage_mount_readonly"] = bool( os.statvfs(MINEBD_STORAGE_PATH).f_flag & ST_RDONLY) outdata["restore_running"] = mbdata["restoreRunning"] outdata["restore_progress"] = mbdata["completedRestorePercent"] else: outdata["minebd_running"] = False outdata["minebd_encrypted"] = None outdata["minebd_storage_mounted"] = False outdata["minebd_storage_mount_readonly"] = None outdata["restore_running"] = False outdata["restore_progress"] = None hasusers = False for user in pwd.getpwall(): if (user.pw_uid >= 1000 and user.pw_uid < 65500 and user.pw_name != "sia" and not user.pw_name.endswith("$")): hasusers = True outdata["users_created"] = hasusers # Only used by minebox-ui which requires minebox-rockstor if is_rockstor_system(): outdata["user_setup_complete"] = rockstor_user_setup() if 'DEMO' in environ: outdata["backup_type"] = "sia_demo" else: outdata["backup_type"] = "sia" consdata, cons_status_code = get_from_sia('consensus') if cons_status_code == 200: outdata["sia_daemon_running"] = True outdata["consensus_height"] = consdata["height"] outdata["consensus_synced"] = consdata["synced"] else: outdata["sia_daemon_running"] = False outdata["consensus_height"] = None outdata["consensus_synced"] = None walletdata, wallet_status_code = get_from_sia('wallet') if username and wallet_status_code == 200: outdata["wallet_unlocked"] = walletdata["unlocked"] outdata["wallet_encrypted"] = walletdata["encrypted"] outdata["wallet_confirmed_balance_sc"] = int( walletdata["confirmedsiacoinbalance"]) / H_PER_SC outdata["wallet_unconfirmed_delta_sc"] = ( int(walletdata["unconfirmedincomingsiacoins"]) - int(walletdata["unconfirmedoutgoingsiacoins"])) / H_PER_SC else: outdata["wallet_unlocked"] = None outdata["wallet_encrypted"] = None outdata["wallet_confirmed_balance_sc"] = None outdata["wallet_unconfirmed_delta_sc"] = None return jsonify(outdata), 200
def api_key_generate(): # Doc: https://bitbucket.org/mineboxgmbh/minebox-client-tools/src/master/doc/mb-ui-gateway-api.md#markdown-header-get-keygenerate mbdata, mb_status_code = get_from_minebd('keys/asJson') # For the moment, just blindly hand over the result from MineBD. return jsonify(mbdata), mb_status_code
def initiate_uploads(status): current_app.logger.info('Starting uploads.') status["message"] = "Starting uploads" status["step"] = sys._getframe().f_code.co_name.replace("_", " ") status["starttime_step"] = time.time() snapname = status["snapname"] backupname = status["backupname"] metadir = path.join(METADATA_BASE, backupname) bfinfo_path = path.join(metadir, INFO_FILENAME) if path.isfile(bfinfo_path): remove(bfinfo_path) sia_filedata, sia_status_code = get_from_sia('renter/files') if sia_status_code == 200: siafiles = sia_filedata["files"] else: return False, "ERROR: sia daemon needs to be running for any uploads." # We have a randomly named subdirectory containing the .dat files. # The subdirectory matches the serial number that MineBD returns. mbdata, mb_status_code = get_from_minebd('serialnumber') if mb_status_code == 200: mbdirname = mbdata["message"] else: return False, "ERROR: Could not get serial number from MineBD." status["backupfileinfo"] = [] status["backupfiles"] = [] status["uploadfiles"] = [] status["backupsize"] = 0 status["uploadsize"] = 0 status["min_redundancy"] = None status["earliest_expiration"] = None for filepath in glob( path.join(DATADIR_MASK, 'snapshots', snapname, mbdirname, '*.dat')): fileinfo = stat(filepath) # Only use files of non-zero size. if fileinfo.st_size: filename = path.basename(filepath) (froot, fext) = path.splitext(filename) sia_fname = '%s.%s%s' % (froot, int(fileinfo.st_mtime), fext) if sia_fname in status["backupfiles"]: # This file is already in the list, and we probably have # multiple lower disks, so omit this file. continue status["backupfiles"].append(sia_fname) status["backupsize"] += fileinfo.st_size if (siafiles and any(sf["siapath"] == sia_fname and sf["available"] and sf["redundancy"] > REDUNDANCY_LIMIT for sf in siafiles)): current_app.logger.info( "%s is part of the set and already uploaded." % sia_fname) elif (siafiles and any(sf["siapath"] == sia_fname for sf in siafiles)): status["uploadsize"] += fileinfo.st_size status["uploadfiles"].append(sia_fname) current_app.logger.info( "%s is part of the set and the upload is already in progress." % sia_fname) else: status["uploadsize"] += fileinfo.st_size status["uploadfiles"].append(sia_fname) current_app.logger.info( "%s has to be uploaded, starting that." % sia_fname) siadata, sia_status_code = post_to_sia( 'renter/upload/%s' % sia_fname, {'source': filepath}) if sia_status_code != 204: return False, ("ERROR: sia upload error %s: %s" % (sia_status_code, siadata["message"])) status["backupfileinfo"].append({ "siapath": sia_fname, "size": fileinfo.st_size }) if not status["backupfiles"]: return False, "ERROR: The backup set has no files, that's impossible." with open(bfinfo_path, 'w') as outfile: json.dump(status["backupfileinfo"], outfile) return True, ""