Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ansible/group_vars/vm_host/ceos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,16 @@ ceos_image_url:
- "http://example1.com/cEOS64-lab-4.29.3M.tar"
- "http://example2.com/cEOS64-lab-4.29.3M.tar"
skip_ceos_image_downloading: false

# Registry settings for pulling ceos docker image. If ceos_registry is defined, the code will first
# check whether ceos_image is already cached locally from the registry, and if not, try to pull it
# from the registry before falling back to the download-and-build approach.
#
# Uncomment ceos_registry and set it to your registry URL to enable registry pulling.
# If the registry requires authentication, also uncomment and set ceos_registry_username and
# ceos_registry_password. If the registry is publicly accessible without authentication, leave the
# username and password commented out.
#
# ceos_registry: "your-registry.example.com"
# ceos_registry_username: "your-username"
# ceos_registry_password: "your-password"
23 changes: 22 additions & 1 deletion ansible/roles/eos/tasks/ceos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,32 @@
- include_tasks: ceos_config.yml
- include_vars: group_vars/vm_host/ceos.yml

- name: Check if ceos_image from registry is available locally
docker_image_info:
name:
- "{{ ceos_registry }}/{{ ceos_image }}"
become: yes
register: ceos_registry_image_info
delegate_to: "{{ VM_host[0] }}"
when: ceos_registry is defined

- name: Set ceos_effective_image
set_fact:
# Use registry-prefixed image name when the registry image is available locally (was pulled
# from registry). This avoids creating a local alias and ensures containers always reference
# the registry image, satisfying security requirements (e.g. Microsoft ACR/MCR policy).
# Fall back to the plain ceos_image name when no registry is configured or registry image
# is not available (e.g. pull failed and image was built from ceos_image_orig instead).
ceos_effective_image: >-
{{ ceos_registry + '/' + ceos_image
if (ceos_registry is defined and ceos_registry_image_info.images | length > 0)
else ceos_image }}

- name: Create cEOS container
become: yes
docker_container:
name: ceos_{{ vm_set_name }}_{{ inventory_hostname }}
image: "{{ ceos_image }}"
image: "{{ ceos_effective_image }}"
command: /sbin/init systemd.setenv=INTFTYPE=eth systemd.setenv=ETBA=1 systemd.setenv=SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 systemd.setenv=CEOS=1 systemd.setenv=EOS_PLATFORM=ceoslab systemd.setenv=container=docker systemd.setenv=MGMT_INTF=eth0
pull: no
state: started
Expand Down
10 changes: 9 additions & 1 deletion ansible/roles/eos/tasks/ceos_ensure_reachable.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
- name: Set ceos_effective_image fallback if not already defined
# ceos_effective_image is normally set by the caller (ceos.yml in the eos role) before this
# file is included. This task provides a safe fallback in case this file is invoked
# independently, so it does not fail with an undefined variable error.
set_fact:
ceos_effective_image: "{{ ceos_image }}"
when: ceos_effective_image is not defined

- block:
- name: set time out threshold
set_fact:
Expand All @@ -18,7 +26,7 @@
become: yes
docker_container:
name: ceos_{{ vm_set_name }}_{{ inventory_hostname }}
image: "{{ ceos_image }}"
image: "{{ ceos_effective_image }}"
command: /sbin/init systemd.setenv=INTFTYPE=eth systemd.setenv=ETBA=1 systemd.setenv=SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 systemd.setenv=CEOS=1 systemd.setenv=EOS_PLATFORM=ceoslab systemd.setenv=container=docker systemd.setenv=MGMT_INTF=eth0
pull: no
state: started
Expand Down
226 changes: 142 additions & 84 deletions ansible/roles/vm_set/tasks/add_ceos_list.yml
Original file line number Diff line number Diff line change
@@ -1,100 +1,158 @@
- name: Check if cEOS docker image exists or not
- name: Check if cEOS docker image exists locally
docker_image_info:
name:
- "{{ ceos_image }}"
become: yes
register: ceos_docker_image_stat
register: ceos_local_image_stat

- name: Check if cEOS docker image from registry is already cached locally
docker_image_info:
name:
- "{{ ceos_registry }}/{{ ceos_image }}"
become: yes
register: ceos_registry_cached_image_stat
when: ceos_registry is defined

- name: Set fact for whether ceos_image is already available
set_fact:
# When registry is defined, only the registry-prefixed image is considered "found" - using
# a local image in that case would bypass the registry requirement (e.g. Microsoft ACR/MCR).
# When registry is not defined, only the locally-named image is considered.
# The | bool filter ensures this is stored as a Python boolean, not the string "True"/"False",
# so that "when: not ceos_image_found" evaluates correctly.
ceos_image_found: "{{ ((ceos_registry is not defined and ceos_local_image_stat.images | length > 0) or
(ceos_registry is defined and ceos_registry_cached_image_stat.images | length > 0)) | bool }}"

- name: Prepare ceos_image if it does not exist
block:

- name: Check if ceos_image_orig exists or not
docker_image_info:
name:
- "{{ ceos_image_orig }}"
become: yes
register: ceos_image_orig_stat
- name: Try to get ceos_image from registry
block:

- name: Login to ceos registry if credentials are defined
become: yes
docker_login:
registry_url: "{{ ceos_registry }}"
username: "{{ ceos_registry_username }}"
password: "{{ ceos_registry_password }}"
when: >
ceos_registry_username is defined and
ceos_registry_password is defined

- name: Pull ceos_image from registry
become: yes
docker_image:
name: "{{ ceos_registry }}/{{ ceos_image }}"
source: pull
register: ceos_registry_pull_result
ignore_errors: yes

- name: Warn that registry pull failed, will fall back to download and build
debug:
msg: >-
WARNING: Failed to pull {{ ceos_registry }}/{{ ceos_image }} from registry.
Will fall back to the download-and-build path. Check ceos_registry and credentials.
when: ceos_registry_pull_result is failed

when: ceos_registry is defined

- name: Prepare ceos_image_orig if it does not exist
- name: Prepare ceos_image via download and build if registry pull failed or registry not defined
block:
- name: Check if local ceos image file exists or not
stat:
path: "{{ root_path }}/images/{{ ceos_image_filename }}"
register: ceos_image_file_stat

- name: Download cEOS image file if no local ceos image file exists
- name: Check if ceos_image_orig exists or not
docker_image_info:
name:
- "{{ ceos_image_orig }}"
become: yes
register: ceos_image_orig_stat

- name: Prepare ceos_image_orig if it does not exist
block:
- name: Fail if skip_ceos_image_downloading is true
fail:
msg: [
"Failed, no ceos docker image, no ceos image file and skip_ceos_image_downloading is true",
"Please manually put cEOS image to {{ root_path }}/images/{{ ceos_image_filename }}"
]
when: skip_ceos_image_downloading == true

- name: Init ceos_image_urls when ceos_image_url value type is string
set_fact:
ceos_image_urls:
- "{{ ceos_image_url }}"
when: ceos_image_url | type_debug == 'string'

- name: Init ceos_image_urls when ceos_image_url value type is list
set_fact:
ceos_image_urls: "{{ ceos_image_url }}"
when: ceos_image_url | type_debug == 'list'

- name: Init working_image_urls list
set_fact:
working_image_urls: []

- name: Loop ceos_image_urls to find out working URLs
include_tasks: probe_image_url.yml
loop: "{{ ceos_image_urls }}"

- name: Fail if no working ceos image download url is found
fail:
msg: [
"Failed, no working ceos image download URL is found. There are 2 options to fix it:",
" 1. Fix ceos_image_url defined in ansible/group_vars/vm_host/ceos.yml",
" 2. Manually put cEOS image to {{ root_path }}/images/{{ ceos_image_filename }}",
]
when: working_image_urls | length == 0

- name: Download cEOS image file from working ceos_image_urls using the first working URL
get_url:
url: "{{ working_image_urls[0] }}"
dest: "{{ root_path }}/images/{{ ceos_image_filename }}"
environment: "{{ proxy_env | default({}) }}"
register: ceos_image_download_result

when: ceos_image_file_stat.stat.exists == false

- name: Import ceos_image_orig docker image
- name: Check if local ceos image file exists or not
stat:
path: "{{ root_path }}/images/{{ ceos_image_filename }}"
register: ceos_image_file_stat

- name: Download cEOS image file if no local ceos image file exists
block:
- name: Fail if skip_ceos_image_downloading is true
fail:
msg: [
"Failed, no ceos docker image, no ceos image file and skip_ceos_image_downloading is true",
"Please manually put cEOS image to {{ root_path }}/images/{{ ceos_image_filename }}"
]
when: skip_ceos_image_downloading == true

- name: Init ceos_image_urls when ceos_image_url value type is string
set_fact:
ceos_image_urls:
- "{{ ceos_image_url }}"
when: ceos_image_url | type_debug == 'string'

- name: Init ceos_image_urls when ceos_image_url value type is list
set_fact:
ceos_image_urls: "{{ ceos_image_url }}"
when: ceos_image_url | type_debug == 'list'

- name: Init working_image_urls list
set_fact:
working_image_urls: []

- name: Loop ceos_image_urls to find out working URLs
include_tasks: probe_image_url.yml
loop: "{{ ceos_image_urls }}"

- name: Fail if no working ceos image download url is found
fail:
msg: [
"Failed, no working ceos image download URL is found. There are 2 options to fix it:",
" 1. Fix ceos_image_url defined in ansible/group_vars/vm_host/ceos.yml",
" 2. Manually put cEOS image to {{ root_path }}/images/{{ ceos_image_filename }}",
]
when: working_image_urls | length == 0

- name: Ensure {{ root_path }}/images exists
file: path={{ root_path }}/images state=directory

- name: Download cEOS image file from working ceos_image_urls using the first working URL
get_url:
url: "{{ working_image_urls[0] }}"
dest: "{{ root_path }}/images/{{ ceos_image_filename }}"
environment: "{{ proxy_env | default({}) }}"
register: ceos_image_download_result

when: ceos_image_file_stat.stat.exists == false

- name: Import ceos_image_orig docker image
become: yes
shell: "docker import {{ root_path }}/images/{{ ceos_image_filename }} {{ ceos_image_orig }}"

when: ceos_image_orig_stat.images | length == 0

- name: Create directory for building ceos docker image
become: yes
file:
path: "/tmp/ceosimage"
state: directory

- name: Copy the ceos image template
become: yes
shell: "docker import {{ root_path }}/images/{{ ceos_image_filename }} {{ ceos_image_orig }}"

when: ceos_image_orig_stat.images | length == 0

- name: Create directory for building ceos docker image
become: yes
file:
path: "/tmp/ceosimage"
state: directory

- name: Copy the ceos image template
become: yes
template: src=ceos_dockerfile.j2 dest=/tmp/ceosimage/Dockerfile mode=0644

- name: Build the ceos image with increasing inotify limit
become: yes
docker_image:
name: "{{ ceos_image }}"
build:
path: "/tmp/ceosimage"
pull: no
source: build

when: ceos_docker_image_stat.images | length == 0
template: src=ceos_dockerfile.j2 dest=/tmp/ceosimage/Dockerfile mode=0644

- name: Build the ceos image with increasing inotify limit
become: yes
docker_image:
name: "{{ ceos_image }}"
build:
path: "/tmp/ceosimage"
pull: no
source: build

when: >
ceos_registry is not defined or
(ceos_registry_pull_result is defined and ceos_registry_pull_result is failed)

when: not ceos_image_found

- name: Create VMs network
become: yes
Expand Down