def process_config(base_config, derived_fn): derived_fn, derived_config = find_and_load_config(derived_fn) base_section = get_section(base_config) derived_section = get_section(derived_config) changed = False inherits = derived_section.get("inherits") _, base_section_name = get_section_name(base_config).split(":") if not base_section_name == inherits: if inherits: print("Something wrong with inherits= in", derived_fn) print("Got '{}' but expected '{}'".format(inherits, base_section_name)) return derived_section['inherits'] = base_section_name changed = True keys = list(derived_section.keys()) for key in keys: if key in base_section and key in derived_section and base_section.get( key) == derived_section.get(key): changed = True del derived_section[key] if changed: print("Removing config values from {} that match its parent(s)".format( derived_fn)) write_config(derived_config, derived_fn)
def determine_ssl_validation(data, certfile=None, insecure=False): if certfile is not None: data["server"]["verify"] = expanduser(certfile) elif insecure: data["server"]["verify"] = False else: data["server"]["verify"] = True common.write_config(data) return data["server"]["verify"]
def toggle_precise(data, mode=None): if mode == "enable": data["precise"] = True elif mode == "disable": data["precise"] = False else: data["precise"] = not data.get("precise", False) common.write_config(data) precise = data.get("precise", True) message = "precise mode: " + str(precise) common.log_output(message, True) return data
def load_config(data, overwrite=False): # If the config file doesn't exist, create it if os.path.isfile(config.CONFIG_FILE) is False or overwrite is True: common.log_output("Creating config file", True) common.write_config(data) # Load the configuration from the config file with io.open(config.CONFIG_FILE, 'r', encoding="UTF-8") as file: try: data = yaml.safe_load(file) common.validate_config(data) return data except yaml.YAMLError as exc: common.log_output(exc, True) sys.exit(2)
def set_parameters_file(data, args, file=None): # Disable parameters file if requested if args.get("disable", False): data.pop("parameters_file", None) common.write_config(data) common.log_output("Disabling parameters-file", True) return data if file is None: return data data["parameters_file"] = file common.write_config(data) common.log_output("Setting parameters-file", True) return data
def login(data, input_url=None, password=None, verify=True, interactive=True, basic_user=None, basic_pass=None): if input_url is None: input_url = "" # Split protocol, url, and port input_url = input_url.replace("/", "").replace("_", "") count = input_url.count(":") protocol = "" url = "" port = "" if count == 2: protocol, url, port = input_url.split(":") elif count == 1 and input_url.index(":") < 6: protocol, url = input_url.split(":") elif count == 1: url, port = input_url.split(":") elif count == 0: url = input_url else: common.log_output("Invalid URL", True) sys.exit(2) # Strip nondigits port = ''.join(re.findall(r'\d+', port)) # Default to config file values for any missing parameters if protocol is None or protocol.lower() not in ["http", "https"]: protocol = data["server"]["protocol"] if url is None or url == "": url = data["server"]["url"] if port is None or port == "": port = data["server"]["port"] # Update config data["server"]["protocol"] = protocol data["server"]["url"] = url data["server"]["port"] = port # Make the login attempt baseurl = common.create_baseurl(data, "") common.log_output("Connecting to " + baseurl + "...", False) r = requests.get(baseurl, allow_redirects=True, verify=verify) common.check_response(data, r.status_code) # Detect if we were redirected to https if "https://" in r.url and protocol != "https": data["server"]["protocol"] = "https" common.log_output("Redirected from http to https", True) # Detect if we're prompted for basic authentication auth_method = r.headers.get('WWW-Authenticate', False) if (auth_method): common.log_output('Basic authentication required...', False) if basic_user is None and interactive: basic_user = input('Basic username: '******'You must provide a basic auth username, --basic-user' common.log_output(message, True) sys.exit(2) if basic_pass is None and interactive: basic_pass = getpass.getpass('Basic password:'******'ascii')) # Create the authorization string basic_auth = "Basic " + secret.decode('utf-8') headers = {"Authorization": basic_auth} r = requests.get(baseurl, verify=verify, headers=headers, allow_redirects=True) common.check_response(data, r.status_code) if r.status_code == 200: common.log_output('Passed basic auth', False) # Update basic auth secret in config file data['authorization'] = basic_auth # Detect if we were prompted to login login_redirect = "/login.html" in r.url if r.status_code == 200 and not login_redirect: common.log_output("OK", False, r.status_code) token = urllib.parse.unquote(r.cookies["xsrf-token"]) elif r.status_code == 200 and login_redirect: password = prompt_password(password, interactive) common.log_output("Getting nonce and salt...", False) baseurl = common.create_baseurl(data, "/login.cgi") headers = common.create_headers(data) payload = {'get-nonce': 1} r = requests.post(baseurl, headers=headers, data=payload, verify=verify) if r.status_code != 200: common.log_output("Error getting salt from server", True, r.status_code) sys.exit(2) salt = r.json()["Salt"] data["nonce"] = urllib.parse.unquote(r.json()["Nonce"]) token = urllib.parse.unquote(r.cookies["xsrf-token"]) common.log_output("Hashing password...", False) salt_password = password.encode() + base64.b64decode(salt) saltedpwd = hashlib.sha256(salt_password).digest() nonce_password = base64.b64decode(data["nonce"]) + saltedpwd noncedpwd = hashlib.sha256(nonce_password).digest() common.log_output("Authenticating... ", False) payload = { "password": base64.b64encode(noncedpwd).decode('utf-8') } cookies = { "xsrf-token": token, "session-nonce": data.get("nonce", "") } r = requests.post(baseurl, headers=headers, data=payload, cookies=cookies, verify=verify) common.check_response(data, r.status_code) if r.status_code == 200: common.log_output("Connected", False, r.status_code) data["session-auth"] = urllib.parse.unquote( r.cookies["session-auth"]) else: message = "Error authenticating against the server" common.log_output(message, True, r.status_code) sys.exit(2) else: message = "Error connecting to server" common.log_output(message, True, r.status_code) sys.exit(2) # Update the config file with provided values data["token"] = token expiration = datetime.datetime.now() + datetime.timedelta(0, 600) data["token_expires"] = expiration data["last_login"] = datetime.datetime.now() common.write_config(data) common.log_output("Login successful", True) return data
def logout(data): common.log_output("Logging out...", True) data['token'] = None data['basic_auth'] = None common.write_config(data) return data
def check_and_update(device, config, run_tests): priorities = common.config_get_list(config, "general", "priority") update_period = common.int_nothrow(config.get("general", "update_period")) now = int(time.time()) tests_alive = check_tests(device.autotest) schedule = get_schedule(device, config) if (tests_alive and not schedule.allow_update): common.log("Schedule forbids updating %s right now" % device.name) return for priority in priorities: # If there are no newer images for this priority: # 1) If this image have been in use for the whole test # duration, check lower priorities # 2) If the tests are still ongoing, abort here latest_list = config.get(device.image_type, priority) latest_onboard = device.config.get("latest_image", priority) last_update = common.int_nothrow( device.config.get("last_update", priority)) enu = last_update + update_period update = check_new_images(latest_list, latest_onboard, now, enu, let_new_override_old(config, priority), tests_alive) if (update == None): if (now >= enu): common.log(" Could update %s to %s but no new images available" % \ (device.name, priority)) continue else: common.log("%s will still run %s" % (device.name, priority)) break last_update = now upload_results = schedule.upload_test_results or not tests_alive tests.stop_tests_and_report(device, upload_results) params = updater.UpdateParams() params.device = device params.update = update params.auth = common.get_auth("dav") params.config = config params.now = now new_image = updater.update(params) if (new_image): latest_onboard = new_image if (run_tests): testset = config.get(device.name, "testset") tests.start_tests(device, config, testset) device.config.set("last_update", priority, str(last_update)) device.config.set("latest_image", priority, latest_onboard) device.config.set("general", "image_type", priority) common.write_config(device.config, device.config_fname) common.log("Updated %s to %s" % (device.name, priority)) else: common.log("Failed to update %s to %s, skipping" % \ (device.name, priority)) break else: common.log("No updates for %s" % device.name)
description="De-duplicate inheriting PrusaSlicer config sections") parser.add_argument( '--out', metavar='SECTION', type=str, required=True, help=f'an output section name (converted to a filename automatically)') parser.add_argument( 'sections', metavar='SECTION', nargs='+', help= f'section filenames (section path prepended automatically if required)' ) args = parser.parse_args() out_section = read_config_and_get_section(args.sections[0]) # pprint(dict(out_section.items())) for section_fn in args.sections[1:]: out_section = intersect_config_sections( out_section, read_config_and_get_section(section_fn)) # pprint(out_section) out_config = create_config() out_config[args.out] = out_section pprint(out_config) write_config(out_config)