Returns the id of the given user name, and creates it first in case it does not exist. A default group is created
    as well.

    :param username: User name.
    :type username: unicode
    :param uid_preset: User id to set in case a new user is created.
    :type uid_preset: int or unicode
    :param groupnames: Additional names of groups to assign the user to. If the user exists, these will be appended to
      existing group assignments.
    :type groupnames: iterable
    :param system: Create a system user.
    :type system: bool
    :param no_login: Disallow login of this user and group, and skip creating the home directory. Default is ``True``.
    :type no_login: bool
    :param no_password: Do not set a password for the new user.
    :type: no_password: bool
    :param gecos: Provide GECOS info and suppress prompt.
    :type gecos: unicode
    :param id_dependent: If the user exists, but its id does not match `uid_preset`, an error is thrown.
    :type id_dependent: bool
    :return:

def get_or_create_user(username, uid_preset, groupnames=[], system=False, no_password=False, no_login=True,
                       gecos=None, id_dependent=True):
    """
    Returns the id of the given user name, and creates it first in case it does not exist. A default group is created
    as well.

    :param username: User name.
    :type username: unicode
    :param uid_preset: User id to set in case a new user is created.
    :type uid_preset: int or unicode
    :param groupnames: Additional names of groups to assign the user to. If the user exists, these will be appended to
      existing group assignments.
    :type groupnames: iterable
    :param system: Create a system user.
    :type system: bool
    :param no_login: Disallow login of this user and group, and skip creating the home directory. Default is ``True``.
    :type no_login: bool
    :param no_password: Do not set a password for the new user.
    :type: no_password: bool
    :param gecos: Provide GECOS info and suppress prompt.
    :type gecos: unicode
    :param id_dependent: If the user exists, but its id does not match `uid_preset`, an error is thrown.
    :type id_dependent: bool
    :return:
    """
    uid = get_user_id(username)
    gid = get_group_id(username)
    if id_dependent and gid is not None and gid != uid_preset:
        error("Present group id '{0}' does not match the required id of the environment '{1}'.".format(gid, uid_preset))
    if gid is None:
        create_group(username, uid_preset, system)
        gid = uid_preset
    if uid is None:
        create_user(username, gid, system, no_login, no_password, False, gecos)
        if groupnames:
            assign_user_groups(username, groupnames)
        return uid
    elif id_dependent and uid != uid_preset:
        error("Present user id '{0}' does not match the required id of the environment '{1}'.".format(uid, uid_preset))
    current_groups = get_user_groups(username)
    new_groups = set(groupnames).discard(tuple(current_groups))
    if new_groups:
        assign_user_groups(username, new_groups)
    return uid