Issues upgrading already installed plugins
janorn opened this issue · 8 comments
Version Information
Ansible: 2.9.27
Role: 3.7.0
Steps to Reproduce
First install docker with this config:
docker_plugins:
- type: authz
alias: opa-docker-authz
name: openpolicyagent/opa-docker-authz-v2:0.4
args: opa-args="-policy-file /opa/policy/authz.rego -quiet"
Second re run role but with upgraded plugin.
docker_plugins:
- type: authz
alias: opa-docker-authz
name: openpolicyagent/opa-docker-authz-v2:0.8
args: opa-args="-policy-file /opa/policy/authz.rego -quiet"
Expected Behavior
Latest version of plugin to be installed.
Actual Behavior
No change.
Before and after this command gives the same output:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@pkrvmmotjxu12cl ~]# docker plugin ls
ID NAME DESCRIPTION ENABLED
d545a1e09604 opa-docker-authz:latest A policy-enabled authorization plugin for Do… true
Close inspection of the plugin after second run show this:
# docker inspect d545a1e09604
...
"Name": "opa-docker-authz:latest",
"PluginReference": "docker.io/openpolicyagent/opa-docker-authz-v2:0.4",
"Settings": {
"Args": [
"-policy-file",
"/opa/policy/authz.rego"
],
"Devices": [],
"Env": [],
"Mounts": [
{
"Description": "",
"Destination": "/opa",
"Name": "policy",
"Options": [
"bind",
"ro"
],
"Settable": [
"source"
],
"Source": "/etc/docker",
"Type": "none"
}
]
}
...
References
Doing some further testing I removed the alias.
First run:
# docker plugin ls
ID NAME DESCRIPTION ENABLED
f3d8d5524631 openpolicyagent/opa-docker-authz-v2:0.4 A policy-enabled authorization plugin for Do… true
Second run:
# docker plugin ls
ID NAME DESCRIPTION ENABLED
f3d8d5524631 openpolicyagent/opa-docker-authz-v2:0.4 A policy-enabled authorization plugin for Do… true
4a972a580a5d openpolicyagent/opa-docker-authz-v2:0.8 A policy-enabled authorization plugin for Do… true
Only the latest plugin was referenced in the daemon.json config.
Then I did a test on the original setup. But running the install manually but same command as in the role.
# docker plugin install --grant-all-permissions --alias opa-docker-authz openpolicyagent/opa-docker-authz-v2:0.8 opa-args="-policy-file /opa/policy/authz.rego" && echo 'installed'
Error response from daemon: plugin opa-docker-authz:latest already exists
For starters you probably should try to pick up that error.
set -o pipefail
However trying to upgrade the plugins manually I noticed that it is tricky. They have to be disabled to be able to remove them.
Perhaps one could have a cleanup process after but then we need to know what was before. I have no good suggestions yet.
I will probably in my case skip alias and make a list of old plugins and add a post-task to remove the old plugins.
Perhaps listing the installed plugins.
# docker plugin ls --format "{{.Name}}\t{{.Enabled}}"
opa-docker-authz:latest true
And disabling them and then run.
# docker plugin upgrade
However it seems like the upgrade command lacks alias so might not be a viable solution.
Thanks for reporting this!
The support in this role for installing plug-ins was a best effort implementation to start with. This because already from the beginning it was a bit complex to do the install since it was not made for automation.
Based on what you have tested related to upgrading plug-ins it seems even more difficult and may increase the role complexity too much.
I have to think about this if there are something that can be done. I will also test the upgrade using the test I have for installing plug-ins.
I have found a workaround for my playbook. To make this work I change the plugin alias slightly. As it is in the example you don't assign a version which lead docker to assign ":latest" to it. For my workaround I have decided to have an incremental version on the alias. This will make it possible to both upgrade plugin and also do changes to the plugin config.
docker_plugins:
- type: authz
alias: opa-docker-authz:20220322
name: openpolicyagent/opa-docker-authz-v2:0.8
args: opa-args="-policy-file /opa/policy/authz.rego -quiet"
Then adding the following tasks to the playbook after the role has executed removes all plugins not listed in docker_plugins.
- name: List installed plugins
become: true
command: "docker plugin ls --format={%raw%}'{{json .}}'{%endraw%}"
register: plugins
- name: Assemble installed plugin list
set_fact:
installed_plugins: "{{ installed_plugins | default([]) | union([item | from_json]) }}"
loop: "{{ plugins.stdout.split('\n') }}"
- name: Find which plugins to remove
set_fact:
old_plugins: "{{ old_plugins | default([]) | union(installed_plugins | selectattr('Name', 'equalto', item)|list) }}"
loop: "{{ (installed_plugins|map(attribute='Name'))|difference(docker_plugins|map(attribute='alias'))|list }}"
- name: Disable old plugins
become: true
command: "docker plugin disable {{ item.Name }}"
when: item.Enabled
loop: "{{ old_plugins | default([]) }}"
- name: Remove old plugins
become: true
command: "docker plugin rm {{ item.Name }}"
loop: "{{ old_plugins | default([]) }}"
Won't fix this in the role. Closing issue.