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)
Beispiel #2
0
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"]
Beispiel #3
0
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
Beispiel #4
0
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)
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
def logout(data):
    common.log_output("Logging out...", True)
    data['token'] = None
    data['basic_auth'] = None
    common.write_config(data)
    return data
Beispiel #8
0
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)
Beispiel #9
0
        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)