Skip to content

Commit

Permalink
feat(image-builder): add force option to remove containers on image b…
Browse files Browse the repository at this point in the history
…uild
  • Loading branch information
yunielrc committed May 22, 2023
1 parent cbca2ba commit 952bdfe
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 74 deletions.
5 changes: 3 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,10 @@
"args": [
"image",
"build",
"-t",
"--force",
"-n",
"image1",
"Vedvfile11"
"Vedvfile"
]
}
]
Expand Down
2 changes: 1 addition & 1 deletion dist/lib/vedv/components/__base/vmobj-service.bash
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ vedv::vmobj_service::__exec_ssh_func() {
fi
readonly workdir

vedv::vmobj_service::start_one "$type" true "$vmobj_id" >/dev/null || {
vedv::vmobj_service::start_one "$type" 'true' "$vmobj_id" >/dev/null || {
err "Failed to start ${type}: ${vmobj_id}"
return "$ERR_VMOBJ_OPERATION"
}
Expand Down
50 changes: 35 additions & 15 deletions dist/lib/vedv/components/image/image-builder.bash
Original file line number Diff line number Diff line change
Expand Up @@ -1071,8 +1071,8 @@ vedv::image_builder::__layer_env() {
# Delete invalid layers
#
# Arguments:
# image_id string image where the files will be copy
# cmds text text with commands (e.g. "1 FROM hello-world")
# image_id string image where the files will be copy
# cmds text text with commands (e.g. "1 FROM hello-world")
#
# Output:
# Writes first_invalid_cmd_pos (int) to the stdout,
Expand Down Expand Up @@ -1397,8 +1397,9 @@ vedv::image_builder::__build() {
# Build image from Vedvfile
#
# Arguments:
# vedvfile string path to Vedvfile
# image_name string name of the image
# vedvfile string path to Vedvfile
# [image_name] string name of the image
# [force] bool force the build removing the image containers
#
# Output:
# Writes image_id (string) image_name (string) and build proccess # output to the stdout
Expand All @@ -1409,34 +1410,27 @@ vedv::image_builder::__build() {
vedv::image_builder::build() {
local -r vedvfile="$1"
local image_name="${2:-}"
local -r force="${3:-false}"
# validate arguments
if [[ -z "$vedvfile" ]]; then
err "Argument 'vedvfile' is required"
return "$ERR_INVAL_ARG"
fi

if [[ ! -f "$vedvfile" ]]; then
err "File '${vedvfile}' does not exist"
return "$ERR_NOT_FOUND"
fi

if [[ -z "$image_name" ]]; then
image_name="$(petname)" || {
err 'Failed to generate a random name for the image'
return "$ERR_IMAGE_BUILDER_OPERATION"
}
fi

local image_id
local image_id=''

___set_image_id_64695() {
image_id="$(vedv::image_entity::get_id_by_image_name "$image_name")" || {
image_id="$(vedv::image_entity::get_id_by_image_name "$image_name")" 2>/dev/null || {
if [[ $? != "$ERR_NOT_FOUND" ]]; then
err "Failed to get image id for image '${image_name}'"
return "$ERR_IMAGE_BUILDER_OPERATION"
fi
}
readonly image_id
# readonly image_id
}

___stop_vm_64695() {
Expand All @@ -1447,6 +1441,32 @@ vedv::image_builder::build() {
}
fi
}
# if the image has containers the force flag must be used to
# run the build removing the containers, otherwise it will fail
if [[ "$force" == false && -n "$image_name" ]]; then
___set_image_id_64695

if [[ -n "$image_id" ]]; then
local has_containers
has_containers="$(vedv::image_entity::has_containers "$image_id")" || {
err "Failed to check if image '${image_name}' has containers"
return "$ERR_IMAGE_BUILDER_OPERATION"
}
readonly has_containers

if [[ "$has_containers" == true ]]; then
err "The image '${image_name}' has containers, you can force the build but the containers will be removed."
return "$ERR_IMAGE_BUILDER_OPERATION"
fi
fi
fi

if [[ -z "$image_name" ]]; then
image_name="$(petname)" || {
err 'Failed to generate a random name for the image'
return "$ERR_IMAGE_BUILDER_OPERATION"
}
fi

vedv::image_builder::__build "$vedvfile" "$image_name" || {
err "The build proccess has failed."
Expand Down
40 changes: 24 additions & 16 deletions dist/lib/vedv/components/image/image-command.bash
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ HELPMSG
#
# Flags:
# [-h | --help] show help
# [--force] force the build removing the image containers
#
# Options:
# [-n | --name | -t] image name
Expand All @@ -242,41 +243,44 @@ HELPMSG
#
vedv::image_command::__build() {
local image_name=''
local vedvfile=''
local force=false
local vedvfile='Vedvfile'

while [[ $# -gt 0 ]]; do
local arg="$1"

case "$arg" in
case "$1" in
-h | --help)
vedv::image_command::__build_help
return 0
;;
-n | --name | -t)
--force)
readonly force=true
shift
image_name="${1:-}"
;;
-n | --name | -t)
image_name="${2:-}"
# validate argument
if [[ -z "$image_name" ]]; then
err "Missing argument for option '${arg}'"
err "No image name specified\n"
vedv::image_command::__build_help
return "$ERR_INVAL_ARG"
fi
shift
shift 2
;;
*)
if [[ -z "$vedvfile" ]]; then
vedvfile="$1"
shift
else
err "Invalid parameter: ${1}\n"
vedv::image_command::__build_help
return "$ERR_INVAL_ARG"
fi
readonly vedvfile="${1:-}"
break
;;
esac
done

vedv::image_service::build "${vedvfile:-Vedvfile}" "$image_name"
if [[ -z "$vedvfile" ]]; then
err "Missing argument 'VEDVFILE'\n"
vedv::image_command::__build_help
return "$ERR_INVAL_ARG"
fi

vedv::image_service::build "$vedvfile" "$image_name" "$force"
}

#
Expand All @@ -292,6 +296,10 @@ ${__VED_IMAGE_COMMAND_SCRIPT_NAME} image build [OPTIONS] [PATH]
Build an image from a Vedvfile
Flags:
-h, --help show the help
--force force the build removing the image containers
Options:
-n, --name, -t image name
HELPMSG
Expand Down
22 changes: 8 additions & 14 deletions dist/lib/vedv/components/image/image-service.bash
Original file line number Diff line number Diff line change
Expand Up @@ -423,22 +423,15 @@ vedv::image_service::child_containers_remove_all() {
fi

local -a container_ids_arr
readarray -t container_ids_arr <<<"$container_ids"
IFS=' ' read -r -a container_ids_arr <<<"$container_ids"
readonly container_ids_arr

local failed_rm_containers=''

for container_id in "${container_ids_arr[@]}"; do
vedv::container_service::remove_one "$container_id" true &>/dev/null || {
failed_rm_containers+="${container_id} "
}
if ! vedv::container_service::remove_one "$container_id" 'true' &>/dev/null; then
err "Failed to remove container: ${container_id}"
return "$ERR_IMAGE_OPERATION"
fi
done
readonly failed_rm_containers

if [[ -n "$failed_rm_containers" ]]; then
err "Failed to remove containers: ${failed_rm_containers}"
return "$ERR_IMAGE_OPERATION"
fi

return 0
}
Expand Down Expand Up @@ -707,8 +700,9 @@ vedv::image_service::get_environment_vars() {
# Build an image from a Vedvfile,
#
# Arguments:
# vedvfile string Vedvfile full path
# [image_name] string name of the image
# vedvfile string Vedvfile full path
# [image_name] string name of the image
# [force] bool force the build, removing child containers if the image has
#
# Output:
# writes process result
Expand Down
21 changes: 21 additions & 0 deletions dist/test/lib/vedv/components/image/image-builder.bats
Original file line number Diff line number Diff line change
Expand Up @@ -2108,6 +2108,9 @@ Failed to stop image 'my-image-name'"
@test 'vedv::image_builder::build() with non existing vedvfile should return an error' {
local -r vedvfile='vedfile-1234454343-abc'

vedv::image_entity::has_containers() {
echo false
}
run vedv::image_builder::build "$vedvfile"

assert_failure
Expand All @@ -2117,6 +2120,9 @@ Failed to stop image 'my-image-name'"
@test 'vedv::image_builder::build() Should fail if image_name generation fails' {
local -r vedvfile='dist/test/lib/vedv/components/image/fixtures/Vedvfile'

vedv::image_entity::has_containers() {
echo false
}
petname() { false; }

run vedv::image_builder::build "$vedvfile"
Expand All @@ -2129,6 +2135,9 @@ Failed to stop image 'my-image-name'"
local -r vedvfile='dist/test/lib/vedv/components/image/fixtures/Vedvfile'
local -r image_name=''

vedv::image_entity::has_containers() {
echo false
}
petname() {
echo 'my-image-name'
}
Expand All @@ -2151,6 +2160,9 @@ Failed to get image id for image 'my-image-name'"
local -r vedvfile='dist/test/lib/vedv/components/image/fixtures/Vedvfile'
local -r image_name=''

vedv::image_entity::has_containers() {
echo false
}
petname() {
echo 'my-image-name'
}
Expand Down Expand Up @@ -2179,6 +2191,9 @@ You must stop and remove it."
local -r vedvfile='dist/test/lib/vedv/components/image/fixtures/Vedvfile'
local -r image_name=''

vedv::image_entity::has_containers() {
echo false
}
petname() {
echo 'my-image-name'
}
Expand Down Expand Up @@ -2210,6 +2225,9 @@ You must remove it."
local -r vedvfile='dist/test/lib/vedv/components/image/fixtures/Vedvfile'
local -r image_name=''

vedv::image_entity::has_containers() {
echo false
}
petname() {
echo 'my-image-name'
}
Expand Down Expand Up @@ -2239,6 +2257,9 @@ The image 'my-image-name' was removed."
local -r vedvfile='dist/test/lib/vedv/components/image/fixtures/Vedvfile'
local -r image_name='my-image-name'

vedv::image_entity::has_containers() {
echo false
}
petname() {
assert_equal "" "INVALID_CALL"
}
Expand Down
22 changes: 7 additions & 15 deletions dist/test/lib/vedv/components/image/image-command.bats
Original file line number Diff line number Diff line change
Expand Up @@ -168,40 +168,32 @@ Build an image from a Vedvfile"
assert_output --partial "$expected_output"
}

@test "vedv::image_command::__build() fails with invalid parameter" {
# Act
run vedv::image_command::__build "foo" "bar"
# Assert
assert_failure "$ERR_INVAL_ARG"
assert_output --partial 'Invalid parameter: bar'
}

@test "vedv::image_command::__build() builds an image from custom Vedvfile" {
# Arrange
local custom_vedvfile="MyVedvfile"
# Stub
vedv::image_service::build() {
assert_regex "$*" '^MyVedvfile\s*$'
assert_regex "$*" '^MyVedvfile false\s*$'
echo "${FUNCNAME[0]} $*"
}
# Act
run vedv::image_command::__build "$custom_vedvfile"
# Assert
assert_success
assert_output --regexp '^vedv::image_service::build MyVedvfile\s*$'
assert_output --regexp '^vedv::image_service::build MyVedvfile false\s*$'
}

@test "vedv::image_command::__build() builds an image from default Vedvfile" {
# Stub
vedv::image_service::build() {
assert_regex "$*" 'Vedvfile\s*'
assert_regex "$*" 'Vedvfile false\s*'
echo "${FUNCNAME[0]} $*"
}
# Act
run vedv::image_command::__build
# Assert
assert_success
assert_output --regexp '^vedv::image_service::build Vedvfile\s*$'
assert_output --regexp '^vedv::image_service::build Vedvfile false\s*$'
}

@test "vedv::image_command::__build() Should fails if -n argument is provided without image name" {
Expand All @@ -217,7 +209,7 @@ Build an image from a Vedvfile"
run vedv::image_command::__build "$arg"
# Assert
assert_failure
assert_output --partial "Missing argument for option '${arg}'"
assert_output --partial "No image name specified"
done
}

Expand All @@ -228,15 +220,15 @@ Build an image from a Vedvfile"
local custom_vedvfile="MyVedvfile"
# Stub
vedv::image_service::build() {
assert_regex "$*" '^MyVedvfile my-image\s*$'
assert_regex "$*" '^MyVedvfile my-image\s* false$'
echo "${FUNCNAME[0]} $*"
}
for arg in '-n' '--name' '-t'; do
# Act
run vedv::image_command::__build "$arg" "$custom_image_name" "$custom_vedvfile"
# Assert
assert_success
assert_output 'vedv::image_service::build MyVedvfile my-image'
assert_output 'vedv::image_service::build MyVedvfile my-image false'
done
}

Expand Down
6 changes: 5 additions & 1 deletion dist/test/lib/vedv/components/image/image-command.f.bats
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ vedv image build [OPTIONS] [PATH]
Build an image from a Vedvfile
Flags:
-h, --help show the help
--force force the build removing the image containers
Options:
-n, --name, -t image name"
done
Expand All @@ -182,7 +186,7 @@ Options:
run vedv image build "$arg"
# Assert
assert_failure
assert_output --partial "Missing argument for option '${arg}'"
assert_output --partial "No image name specified"
done
}

Expand Down
Loading

0 comments on commit 952bdfe

Please sign in to comment.