diff --git a/changelogs/fragments/docker-logout-newer-docker.yml b/changelogs/fragments/docker-logout-newer-docker.yml new file mode 100644 index 00000000000..90b282d8748 --- /dev/null +++ b/changelogs/fragments/docker-logout-newer-docker.yml @@ -0,0 +1,3 @@ +bugfixes: + - docker_login - now correctly reports changed status on logout for Docker versions released after June 2020. + - docker_login - now obeys check_mode for logout diff --git a/lib/ansible/modules/cloud/docker/docker_login.py b/lib/ansible/modules/cloud/docker/docker_login.py index 3fac04e4baf..c09e39b6e8b 100644 --- a/lib/ansible/modules/cloud/docker/docker_login.py +++ b/lib/ansible/modules/cloud/docker/docker_login.py @@ -214,6 +214,21 @@ class LoginManager(DockerBaseClass): :return: None ''' + # Newer docker returns the same "Removing login credentials" message + # regardless of whether or not we are already logged out. + # So to try to determine ourselves, we try reading the config if we can + # and looking at the 'auths' section. Then we do it again after, and + # compare. + path = self.config_path + found_config = self.config_file_exists(path) + if found_config: + has_auth = self.auth_in_config(path) + # This is also enough to restore check_mode functionality + # If it's in the config, then logging out should remove it. + if self.check_mode: + self.results['changed'] = has_auth + return + cmd = [self.client.module.get_bin_path('docker', True), "logout", self.registry_url] # TODO: docker does not support config file in logout, restore this when they do # if self.config_path and self.config_file_exists(self.config_path): @@ -225,7 +240,15 @@ class LoginManager(DockerBaseClass): if 'Not logged in to ' in out: self.results['changed'] = False elif 'Removing login credentials for ' in out: - self.results['changed'] = True + # See note above about this. + if found_config: + has_auth_after_logout = self.auth_in_config(path) + self.results['changed'] = has_auth != has_auth_after_logout + else: + # If we didn't find a config, something weird likely happened. + # We lose idempotency here, but keep the backwards compatible + # behavior instead of erroring. + self.results['changed'] = True else: self.client.module.warn('Unable to determine whether logout was successful.') @@ -239,6 +262,15 @@ class LoginManager(DockerBaseClass): self.log("Configuration file %s not found." % (path)) return False + def auth_in_config(self, path): + try: + with open(path, "r") as file: + config = json.load(file) + return self.registry_url in config.get('auths', {}) + except ValueError: + self.log("Error reading config from %s" % (path)) + return False + def create_config_file(self, path): ''' Create a config file with a JSON blob containing an auths key. diff --git a/test/integration/targets/docker-registry/tasks/tests/docker_login.yml b/test/integration/targets/docker-registry/tasks/tests/docker_login.yml index 3f931ec7778..30a20dbf3d7 100644 --- a/test/integration/targets/docker-registry/tasks/tests/docker_login.yml +++ b/test/integration/targets/docker-registry/tasks/tests/docker_login.yml @@ -68,12 +68,12 @@ - login_3 is not changed - login_4 is not changed -#- name: Log out (check mode) -# docker_login: -# registry_url: "{{ registry_frontend_address }}" -# state: absent -# register: logout_1 -# check_mode: yes +- name: Log out (check mode) + docker_login: + registry_url: "{{ registry_frontend_address }}" + state: absent + register: logout_1 + check_mode: yes - name: Log out docker_login: @@ -94,10 +94,10 @@ register: logout_4 check_mode: yes -- name: Make sure that login worked +- name: Make sure that logout worked assert: that: - #- logout_1 is changed + - logout_1 is changed - logout_2 is changed - logout_3 is not changed - logout_4 is not changed diff --git a/test/integration/targets/setup_docker/tasks/Fedora.yml b/test/integration/targets/setup_docker/tasks/Fedora.yml index 9f52e8f1441..5f71b849cb3 100644 --- a/test/integration/targets/setup_docker/tasks/Fedora.yml +++ b/test/integration/targets/setup_docker/tasks/Fedora.yml @@ -1,3 +1,8 @@ +- name: Import GPG key + rpm_key: + key: https://download.docker.com/linux/fedora/gpg + state: present + - name: Add repository yum_repository: file: docker-ce @@ -6,7 +11,6 @@ baseurl: https://download.docker.com/linux/fedora/$releasever/$basearch/stable enabled: yes gpgcheck: yes - gpgkey: https://download.docker.com/linux/fedora/gpg - name: Update cache command: dnf makecache