Try to inject the parent image in slopslopstrap
This commit is contained in:
288
sloptrap
288
sloptrap
@@ -245,6 +245,7 @@ CAPABILITY_TRUST_ROOT_HOST=""
|
||||
CAPABILITY_TRUST_FILE_HOST=""
|
||||
CAPABILITY_BUILD_STAMP_HOST=""
|
||||
CAPABILITY_STATE_HOST=""
|
||||
CAPABILITY_PRELOAD_DIR_HOST=""
|
||||
IGNORE_STUB_BASE=""
|
||||
IGNORE_HELPER_ROOT=""
|
||||
ALLOW_HOST_NETWORK=false
|
||||
@@ -355,6 +356,7 @@ write_embedded_helper() {
|
||||
set -euo pipefail
|
||||
|
||||
helper_pid=""
|
||||
helperd_bin=${SLOPTRAP_HELPERD_BIN:-/usr/local/bin/sloptrap-helperd}
|
||||
|
||||
has_capability() {
|
||||
local needle=$1
|
||||
@@ -440,12 +442,16 @@ lookup_account_name() {
|
||||
|
||||
ensure_subid_mappings() {
|
||||
local account_id account_gid account_name=""
|
||||
local subuid_file subgid_file
|
||||
local range_start="" range_count="" gid_start="" gid_count=""
|
||||
local detected_range=""
|
||||
|
||||
account_id=${SLOPTRAP_HOST_UID:-$(id -u)}
|
||||
account_gid=${SLOPTRAP_HOST_GID:-$(id -g)}
|
||||
if ! account_name=$(lookup_account_name "$account_id"); then
|
||||
account_name=${SLOPTRAP_HOST_USER:-}
|
||||
subuid_file=${SLOPTRAP_PODMAN_SUBUID_FILE:-/etc/subuid}
|
||||
subgid_file=${SLOPTRAP_PODMAN_SUBGID_FILE:-/etc/subgid}
|
||||
if [[ -z $account_name ]] && ! account_name=$(lookup_account_name "$account_id"); then
|
||||
account_name=""
|
||||
fi
|
||||
|
||||
@@ -463,10 +469,10 @@ ensure_subid_mappings() {
|
||||
fi
|
||||
|
||||
if [[ -n $range_start && -n $range_count ]]; then
|
||||
ensure_subid_mapping_file /etc/subuid "$account_name" "$account_id" "$range_start" "$range_count"
|
||||
ensure_subid_mapping_file "$subuid_file" "$account_name" "$account_id" "$range_start" "$range_count"
|
||||
fi
|
||||
if [[ -n $gid_start && -n $gid_count ]]; then
|
||||
ensure_subid_mapping_file /etc/subgid "$account_name" "$account_id" "$gid_start" "$gid_count"
|
||||
ensure_subid_mapping_file "$subgid_file" "$account_name" "$account_id" "$gid_start" "$gid_count"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -495,7 +501,7 @@ if [[ $(id -u) -eq 0 ]]; then
|
||||
ensure_subid_mappings
|
||||
fi
|
||||
if [[ -n ${SLOPTRAP_ACTIVE_CAPABILITIES:-} ]]; then
|
||||
/usr/local/bin/sloptrap-helperd &
|
||||
"$helperd_bin" &
|
||||
helper_pid=$!
|
||||
fi
|
||||
if [[ -n $target_uid && -n $target_gid ]]; then
|
||||
@@ -1129,7 +1135,7 @@ has_capability() {
|
||||
}
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
printf 'usage: sloppodman <pull|build|tag|run|ps|logs|stop|rm|inspect> ...\n' >&2
|
||||
printf 'usage: sloppodman <pull|build|tag|load|import|run|ps|logs|stop|rm|inspect> ...\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
@@ -1139,7 +1145,7 @@ shift
|
||||
subcommand_prefix=("$subcommand")
|
||||
|
||||
case "$subcommand" in
|
||||
pull|build|tag|run|ps|logs|stop|rm|inspect|rmi)
|
||||
pull|build|tag|load|import|run|ps|logs|stop|rm|inspect|rmi)
|
||||
;;
|
||||
image)
|
||||
[[ $# -gt 0 ]] || {
|
||||
@@ -1204,6 +1210,7 @@ CONTAINERS_CONF_EOF
|
||||
export CONTAINERS_STORAGE_CONF="$storage_conf"
|
||||
export CONTAINERS_CONF="$containers_conf"
|
||||
export BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}"
|
||||
export _CONTAINERS_USERNS_CONFIGURED="${_CONTAINERS_USERNS_CONFIGURED:-done}"
|
||||
|
||||
detect_subid_range_from_map() {
|
||||
local map_path=$1
|
||||
@@ -1320,6 +1327,7 @@ exec_podman() {
|
||||
CONTAINERS_STORAGE_CONF="$CONTAINERS_STORAGE_CONF" \
|
||||
CONTAINERS_CONF="$CONTAINERS_CONF" \
|
||||
BUILDAH_ISOLATION="$BUILDAH_ISOLATION" \
|
||||
_CONTAINERS_USERNS_CONFIGURED="$_CONTAINERS_USERNS_CONFIGURED" \
|
||||
XDG_RUNTIME_DIR="$runtime_dir" \
|
||||
SLOPTRAP_PODMAN_ESCALATED=1 \
|
||||
SLOPTRAP_PODMAN_CALLER_UID="${SLOPTRAP_PODMAN_CALLER_UID:-$(id -u)}" \
|
||||
@@ -1352,6 +1360,19 @@ validate_workspace_path() {
|
||||
esac
|
||||
}
|
||||
|
||||
validate_archive_path() {
|
||||
local path=$1
|
||||
local resolved allowed_archive=""
|
||||
resolved=$(resolve_inner_path "$path")
|
||||
if [[ -n ${SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE:-} ]]; then
|
||||
allowed_archive=$(resolve_inner_path "$SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE")
|
||||
if [[ $resolved == "$allowed_archive" ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
validate_workspace_path "$path"
|
||||
}
|
||||
|
||||
reject_flag() {
|
||||
local flag=$1
|
||||
printf 'sloppodman: %s is not permitted\n' "$flag" >&2
|
||||
@@ -1450,6 +1471,60 @@ if [[ $subcommand == "build" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $subcommand == "import" ]]; then
|
||||
args=("$@")
|
||||
archive_path=""
|
||||
idx=0
|
||||
while (( idx < ${#args[@]} )); do
|
||||
arg=${args[$idx]}
|
||||
case "$arg" in
|
||||
--change|--message)
|
||||
((idx+=1))
|
||||
(( idx < ${#args[@]} )) || { printf 'sloppodman: %s requires a value\n' "$arg" >&2; exit 2; }
|
||||
;;
|
||||
--change=*|--message=*|-q|--quiet)
|
||||
;;
|
||||
-*)
|
||||
;;
|
||||
*)
|
||||
archive_path=$arg
|
||||
break
|
||||
;;
|
||||
esac
|
||||
((idx+=1))
|
||||
done
|
||||
[[ -n $archive_path ]] || { printf 'sloppodman: import requires an archive path\n' >&2; exit 2; }
|
||||
validate_archive_path "$archive_path"
|
||||
fi
|
||||
|
||||
if [[ $subcommand == "load" ]]; then
|
||||
args=("$@")
|
||||
archive_path=""
|
||||
idx=0
|
||||
while (( idx < ${#args[@]} )); do
|
||||
arg=${args[$idx]}
|
||||
case "$arg" in
|
||||
-i|--input)
|
||||
((idx+=1))
|
||||
(( idx < ${#args[@]} )) || { printf 'sloppodman: %s requires a path\n' "$arg" >&2; exit 2; }
|
||||
archive_path=${args[$idx]}
|
||||
;;
|
||||
--input=*|-i=*)
|
||||
archive_path=${arg#*=}
|
||||
;;
|
||||
-*)
|
||||
;;
|
||||
*)
|
||||
archive_path=$arg
|
||||
break
|
||||
;;
|
||||
esac
|
||||
((idx+=1))
|
||||
done
|
||||
[[ -n $archive_path ]] || { printf 'sloppodman: load requires an archive path\n' >&2; exit 2; }
|
||||
validate_archive_path "$archive_path"
|
||||
fi
|
||||
|
||||
if [[ $subcommand == "run" ]]; then
|
||||
args=("$@")
|
||||
idx=0
|
||||
@@ -1684,6 +1759,7 @@ select_capability_state_paths() {
|
||||
CAPABILITY_TRUST_FILE_HOST="$CAPABILITY_TRUST_ROOT_HOST/$CODEX_STATE_KEY.trust"
|
||||
CAPABILITY_BUILD_STAMP_HOST="$capability_root/builds/$CODEX_STATE_KEY.stamp"
|
||||
CAPABILITY_STATE_HOST="$CODEX_STATE_HOME_HOST/capabilities"
|
||||
CAPABILITY_PRELOAD_DIR_HOST="$CAPABILITY_STATE_HOST/podman-preload"
|
||||
}
|
||||
|
||||
ensure_capability_state_paths() {
|
||||
@@ -1696,6 +1772,7 @@ ensure_capability_state_paths() {
|
||||
ensure_codex_directory "$CAPABILITY_STATE_HOST/podman-storage" "nested podman storage state"
|
||||
ensure_codex_directory "$CAPABILITY_STATE_HOST/podman-run" "nested podman runroot state"
|
||||
ensure_codex_directory "$CAPABILITY_STATE_HOST/podman-runtime" "nested podman runtime state"
|
||||
ensure_codex_directory "$CAPABILITY_PRELOAD_DIR_HOST" "nested podman preload state"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1768,6 +1845,16 @@ capability_build_stamp_matches_current() {
|
||||
[[ $stamp_digest == "$CAPABILITY_MANIFEST_DIGEST" && $stamp_caps == "$REQUESTED_CAPABILITIES" ]]
|
||||
}
|
||||
|
||||
run_with_nested_podman_root() {
|
||||
if capability_list_contains "${SLOPTRAP_ACTIVE_CAPABILITIES:-}" "nested-podman" \
|
||||
&& [[ $(id -u) -ne 0 ]] \
|
||||
&& command -v setpriv >/dev/null 2>&1; then
|
||||
setpriv --reuid 0 --regid 0 --clear-groups -- "$@"
|
||||
return
|
||||
fi
|
||||
"$@"
|
||||
}
|
||||
|
||||
assert_path_within_code_dir() {
|
||||
local candidate=$1
|
||||
local resolved
|
||||
@@ -2057,7 +2144,9 @@ detect_container_engine() {
|
||||
local override=${SLOPTRAP_CONTAINER_ENGINE-}
|
||||
if [[ -n $override ]]; then
|
||||
local engine="${override,,}"
|
||||
if ! command -v "$engine" >/dev/null 2>&1; then
|
||||
if [[ $engine == */* ]]; then
|
||||
[[ -x $engine ]] || error "container engine '$engine' is not executable"
|
||||
elif ! command -v "$engine" >/dev/null 2>&1; then
|
||||
error "container engine '$engine' not found in PATH"
|
||||
fi
|
||||
printf '%s' "$engine"
|
||||
@@ -2706,6 +2795,7 @@ prepare_container_runtime() {
|
||||
-v "$CAPABILITY_STATE_HOST/podman-storage:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/storage$SLOPTRAP_VOLUME_LABEL"
|
||||
-v "$CAPABILITY_STATE_HOST/podman-run:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/run$SLOPTRAP_VOLUME_LABEL"
|
||||
-v "$CAPABILITY_STATE_HOST/podman-runtime:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/runtime$SLOPTRAP_VOLUME_LABEL"
|
||||
-v "$CAPABILITY_PRELOAD_DIR_HOST:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/preload$SLOPTRAP_VOLUME_LABEL"
|
||||
)
|
||||
fi
|
||||
|
||||
@@ -2728,14 +2818,24 @@ prepare_container_runtime() {
|
||||
if capability_list_contains "$ENABLED_CAPABILITIES" "nested-podman" && [[ $SLOPTRAP_NETWORK_NAME == "host" ]]; then
|
||||
env_args+=(-e "SLOPTRAP_INNER_PODMAN_HOST_NETWORK=1")
|
||||
fi
|
||||
if capability_list_contains "$ENABLED_CAPABILITIES" "nested-podman"; then
|
||||
env_args+=(
|
||||
-e "SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE=$(recursive_preload_archive_container_path)"
|
||||
-e "SLOPTRAP_RECURSIVE_PARENT_IMAGE_NAME=$SLOPTRAP_IMAGE_NAME"
|
||||
)
|
||||
fi
|
||||
|
||||
local uid gid
|
||||
local uid gid user
|
||||
uid=$(id -u)
|
||||
gid=$(id -g)
|
||||
user=$(id -un 2>/dev/null || true)
|
||||
env_args+=(
|
||||
-e "SLOPTRAP_HOST_UID=$uid"
|
||||
-e "SLOPTRAP_HOST_GID=$gid"
|
||||
)
|
||||
if [[ -n $user ]]; then
|
||||
env_args+=(-e "SLOPTRAP_HOST_USER=$user")
|
||||
fi
|
||||
local -a user_opts=("--user" "$uid:$gid")
|
||||
if [[ $CONTAINER_ENGINE == "podman" ]]; then
|
||||
user_opts=(--userns="keep-id:uid=$uid,gid=$gid" "${user_opts[@]}")
|
||||
@@ -2860,6 +2960,169 @@ rebuild_image() {
|
||||
write_capability_build_stamp
|
||||
}
|
||||
|
||||
compute_recursive_preload_stamp() {
|
||||
local launcher_source=${BASH_SOURCE[0]:-$0}
|
||||
local launcher_digest
|
||||
launcher_digest=$(sha256sum "$launcher_source")
|
||||
printf '%s\n%s\n' "${launcher_digest%% *}" "$SLOPTRAP_IMAGE_NAME"
|
||||
}
|
||||
|
||||
recursive_preload_archive_host_path() {
|
||||
printf '%s/%s.tar\n' "$CAPABILITY_PRELOAD_DIR_HOST" "$SLOPTRAP_IMAGE_NAME"
|
||||
}
|
||||
|
||||
recursive_preload_archive_container_path() {
|
||||
printf '%s/capabilities/podman/preload/%s.tar\n' "$SLOPTRAP_CODEX_HOME_CONT" "$SLOPTRAP_IMAGE_NAME"
|
||||
}
|
||||
|
||||
prepare_recursive_parent_image_preload() {
|
||||
capability_list_contains "$ENABLED_CAPABILITIES" "nested-podman" || return 0
|
||||
local engine_name=${CONTAINER_ENGINE##*/}
|
||||
case "$engine_name" in
|
||||
sloppodman|sloppodman*|.sloppodman*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
local archive_path stamp_path image_id recorded_id=""
|
||||
archive_path=$(recursive_preload_archive_host_path)
|
||||
stamp_path="${archive_path}.stamp"
|
||||
if ! image_id=$("$CONTAINER_ENGINE" image inspect --format '{{.Id}}' "$SLOPTRAP_IMAGE_NAME" 2>/dev/null); then
|
||||
return 1
|
||||
fi
|
||||
if [[ -f $archive_path && -f $stamp_path ]]; then
|
||||
recorded_id=$(sed -n '1p' "$stamp_path" 2>/dev/null || true)
|
||||
if [[ $recorded_id == "$image_id" ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
local tmp_archive="${archive_path}.tmp"
|
||||
if ! "$CONTAINER_ENGINE" save -o "$tmp_archive" "$SLOPTRAP_IMAGE_NAME"; then
|
||||
rm -f "$tmp_archive"
|
||||
return 1
|
||||
fi
|
||||
mv "$tmp_archive" "$archive_path"
|
||||
printf '%s\n%s\n' "$image_id" "$SLOPTRAP_IMAGE_NAME" >"$stamp_path"
|
||||
}
|
||||
|
||||
load_recursive_parent_image() {
|
||||
local engine_name=${CONTAINER_ENGINE##*/}
|
||||
local archive_path=${SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE:-}
|
||||
local source_image_name=${SLOPTRAP_RECURSIVE_PARENT_IMAGE_NAME:-$SLOPTRAP_IMAGE_NAME}
|
||||
case "$engine_name" in
|
||||
sloppodman|sloppodman*|.sloppodman*)
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
capability_list_contains "${SLOPTRAP_ACTIVE_CAPABILITIES:-}" "nested-podman" || return 1
|
||||
[[ -n $archive_path && -r $archive_path ]] || return 1
|
||||
|
||||
if ! "$CONTAINER_ENGINE" load -i "$archive_path"; then
|
||||
return 1
|
||||
fi
|
||||
if ! "$CONTAINER_ENGINE" image inspect "$SLOPTRAP_IMAGE_NAME" >/dev/null 2>&1; then
|
||||
[[ -n $source_image_name ]] || return 1
|
||||
"$CONTAINER_ENGINE" tag "$source_image_name" "$SLOPTRAP_IMAGE_NAME" || return 1
|
||||
fi
|
||||
"$CONTAINER_ENGINE" image inspect "$SLOPTRAP_IMAGE_NAME" >/dev/null 2>&1 || return 1
|
||||
write_capability_build_stamp
|
||||
return 0
|
||||
}
|
||||
|
||||
prepare_recursive_parent_image_archive() {
|
||||
local archive_dir="$CODE_DIR/.sloptrap-preload"
|
||||
local archive_path="$archive_dir/${SLOPTRAP_IMAGE_NAME}.tar"
|
||||
local stamp_path="$archive_path.stamp"
|
||||
local desired_stamp current_stamp=""
|
||||
desired_stamp=$(compute_recursive_preload_stamp)
|
||||
if [[ -f $archive_path && -f $stamp_path ]]; then
|
||||
current_stamp=$(cat "$stamp_path" 2>/dev/null || true)
|
||||
if [[ $current_stamp == "$desired_stamp" ]]; then
|
||||
printf '%s\n' "$archive_path"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
assert_path_within_code_dir "$archive_dir"
|
||||
mkdir -p "$archive_dir"
|
||||
|
||||
local overlay_dir
|
||||
overlay_dir=$(create_temp_dir "recursive-preload")
|
||||
local helper
|
||||
for helper in sloptrap-entrypoint sloptrap-helperd slop-apt slopcap sloppodman; do
|
||||
populate_embedded_helper "$helper" "$overlay_dir/usr/local/bin/$helper"
|
||||
done
|
||||
chmod 0755 \
|
||||
"$overlay_dir/usr/local/bin/sloptrap-entrypoint" \
|
||||
"$overlay_dir/usr/local/bin/sloptrap-helperd" \
|
||||
"$overlay_dir/usr/local/bin/slop-apt" \
|
||||
"$overlay_dir/usr/local/bin/slopcap" \
|
||||
"$overlay_dir/usr/local/bin/sloppodman"
|
||||
|
||||
local tmp_archive="$archive_path.tmp"
|
||||
rm -f "$tmp_archive"
|
||||
if ! run_with_nested_podman_root tar --numeric-owner --one-file-system \
|
||||
--exclude=./proc \
|
||||
--exclude=./sys \
|
||||
--exclude=./dev \
|
||||
--exclude=./run \
|
||||
--exclude=./tmp \
|
||||
--exclude=./workspace \
|
||||
--exclude=./codex \
|
||||
--exclude=./usr/local/bin/sloptrap-entrypoint \
|
||||
--exclude=./usr/local/bin/sloptrap-helperd \
|
||||
--exclude=./usr/local/bin/slop-apt \
|
||||
--exclude=./usr/local/bin/slopcap \
|
||||
--exclude=./usr/local/bin/sloppodman \
|
||||
-cf "$tmp_archive" -C / .; then
|
||||
rm -f "$tmp_archive"
|
||||
return 1
|
||||
fi
|
||||
if ! tar --numeric-owner -rf "$tmp_archive" -C "$overlay_dir" .; then
|
||||
rm -f "$tmp_archive"
|
||||
return 1
|
||||
fi
|
||||
mv "$tmp_archive" "$archive_path"
|
||||
printf '%s\n' "$desired_stamp" >"$stamp_path"
|
||||
printf '%s\n' "$archive_path"
|
||||
}
|
||||
|
||||
import_recursive_parent_image() {
|
||||
local engine_name=${CONTAINER_ENGINE##*/}
|
||||
local archive_path=${SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE:-}
|
||||
case "$engine_name" in
|
||||
sloppodman|sloppodman*|.sloppodman*)
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
capability_list_contains "${SLOPTRAP_ACTIVE_CAPABILITIES:-}" "nested-podman" || return 1
|
||||
|
||||
if [[ -n $archive_path ]]; then
|
||||
[[ -r $archive_path ]] || return 1
|
||||
else
|
||||
if ! archive_path=$(prepare_recursive_parent_image_archive); then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! "$CONTAINER_ENGINE" import \
|
||||
--change 'ENTRYPOINT ["/usr/local/bin/sloptrap-entrypoint"]' \
|
||||
--change 'WORKDIR /workspace' \
|
||||
--change 'ENV SHELL=/bin/bash' \
|
||||
--change 'ENV HOME=/home/sloptrap' \
|
||||
--change "LABEL $SLOPTRAP_IMAGE_LABEL" \
|
||||
"$archive_path" \
|
||||
"$SLOPTRAP_IMAGE_NAME"; then
|
||||
return 1
|
||||
fi
|
||||
write_capability_build_stamp
|
||||
return 0
|
||||
}
|
||||
|
||||
build_if_missing() {
|
||||
ensure_capability_trust
|
||||
if $DRY_RUN; then
|
||||
@@ -2888,6 +3151,12 @@ build_if_missing() {
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
if load_recursive_parent_image; then
|
||||
return 0
|
||||
fi
|
||||
if import_recursive_parent_image; then
|
||||
return 0
|
||||
fi
|
||||
build_image
|
||||
}
|
||||
|
||||
@@ -2934,6 +3203,7 @@ prune_sloptrap_images() {
|
||||
run_codex_command() {
|
||||
local -a extra_args=("$@")
|
||||
ensure_codex_storage_paths
|
||||
prepare_recursive_parent_image_preload || true
|
||||
local -a cmd=("${BASE_CONTAINER_CMD[@]}" "$SLOPTRAP_IMAGE_NAME" "codex")
|
||||
if [[ ${#CODEX_ARGS_ARRAY[@]} -gt 0 ]]; then
|
||||
cmd+=("${CODEX_ARGS_ARRAY[@]}")
|
||||
@@ -2955,6 +3225,7 @@ run_codex() {
|
||||
|
||||
run_login_target() {
|
||||
ensure_codex_storage_paths
|
||||
prepare_recursive_parent_image_preload || true
|
||||
if ! $DRY_RUN; then
|
||||
status_line "Login %s\n" "$SLOPTRAP_IMAGE_NAME"
|
||||
fi
|
||||
@@ -2964,6 +3235,7 @@ run_login_target() {
|
||||
|
||||
run_shell_target() {
|
||||
ensure_codex_storage_paths
|
||||
prepare_recursive_parent_image_preload || true
|
||||
if ! $DRY_RUN; then
|
||||
status_line "Shell %s\n" "$SLOPTRAP_IMAGE_NAME"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user