From 01d3da982d65fb8442cbd78c7393224467eba7c6 Mon Sep 17 00:00:00 2001 From: Flox Date: Sat, 22 Sep 2018 14:59:25 -0400 Subject: [PATCH] Add Support for Docker run command arguments or some docker containers, it can be useful--if not necessary--to run add arguments to the docker run command. Modeled after the "options" object for Rockons' definitions, this commit adds support for such arguments to Rockons by: 1. Fetching arguments from a "cmd_arguments" object at the "container" level in the JSON file. Similar to the current 'options' object, this object must be in a 2-d array: "cmd_arguments": [ ["cowsay", "argument1"] ]. 1. Store arguments in storageadmin under a new DContainerArgs table. 3. Extend the docker run call with these arguments after inserting the container's image name. --- .../migrations/0006_dcontainerargs.py | 23 +++++++++++++++++++ src/rockstor/storageadmin/models/__init__.py | 2 +- src/rockstor/storageadmin/models/rockon.py | 9 ++++++++ src/rockstor/storageadmin/views/rockon.py | 18 ++++++++++++++- .../storageadmin/views/rockon_helpers.py | 12 +++++++++- 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 src/rockstor/storageadmin/migrations/0006_dcontainerargs.py diff --git a/src/rockstor/storageadmin/migrations/0006_dcontainerargs.py b/src/rockstor/storageadmin/migrations/0006_dcontainerargs.py new file mode 100644 index 000000000..6b96c9f17 --- /dev/null +++ b/src/rockstor/storageadmin/migrations/0006_dcontainerargs.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('storageadmin', '0005_auto_20180913_0923'), + ] + + operations = [ + migrations.CreateModel( + name='DContainerArgs', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('name', models.CharField(max_length=1024)), + ('val', models.CharField(max_length=1024, blank=True)), + ('container', models.ForeignKey(to='storageadmin.DContainer')), + ], + ), + ] diff --git a/src/rockstor/storageadmin/models/__init__.py b/src/rockstor/storageadmin/models/__init__.py index 66b2f273e..26adfb36b 100644 --- a/src/rockstor/storageadmin/models/__init__.py +++ b/src/rockstor/storageadmin/models/__init__.py @@ -45,7 +45,7 @@ from tls_certificate import TLSCertificate # noqa E501 from rockon import (RockOn, DImage, DContainer, DPort, DVolume, # noqa E501 ContainerOption, DCustomConfig, DContainerLink, # noqa E501 - DContainerEnv, DContainerDevice) # noqa E501 + DContainerEnv, DContainerDevice, DContainerArgs) # noqa E501 from smart import (SMARTAttribute, SMARTCapability, SMARTErrorLog, # noqa E501 SMARTErrorLogSummary, SMARTTestLog, SMARTTestLogDetail, # noqa E501 SMARTIdentity, SMARTInfo) # noqa E501 diff --git a/src/rockstor/storageadmin/models/rockon.py b/src/rockstor/storageadmin/models/rockon.py index 40ab91e15..f9d0eddba 100644 --- a/src/rockstor/storageadmin/models/rockon.py +++ b/src/rockstor/storageadmin/models/rockon.py @@ -126,6 +126,15 @@ class Meta: app_label = 'storageadmin' +class DContainerArgs(models.Model): + container = models.ForeignKey(DContainer) + name = models.CharField(max_length=1024) + val = models.CharField(max_length=1024, blank=True) + + class Meta: + app_label = 'storageadmin' + + class DCustomConfig(models.Model): rockon = models.ForeignKey(RockOn) key = models.CharField(max_length=1024) diff --git a/src/rockstor/storageadmin/views/rockon.py b/src/rockstor/storageadmin/views/rockon.py index 571e11929..887f98e43 100644 --- a/src/rockstor/storageadmin/views/rockon.py +++ b/src/rockstor/storageadmin/views/rockon.py @@ -24,7 +24,7 @@ from storageadmin.models import (RockOn, DImage, DContainer, DPort, DVolume, ContainerOption, DCustomConfig, DContainerLink, DContainerEnv, - DContainerDevice) + DContainerDevice, DContainerArgs) from storageadmin.serializers import RockOnSerializer from storageadmin.util import handle_exception import rest_framework_custom as rfc @@ -320,6 +320,22 @@ def _create_update_meta(self, name, r_d): if (oo.id not in id_l): oo.delete() + cmd_args = containers[c].get('cmd_arguments', []) + id_l = [] + for ca in cmd_args: + # there are no unique constraints on this model, so we need + # this bandaid. + if (DContainerArgs.objects.filter( + container=co, name=ca[0], val=ca[1]).count() > 1): + DContainerArgs.objects.filter( + container=co, name=ca[0], val=ca[1]).delete() + cao, created = DContainerArgs.objects.get_or_create( + container=co, name=ca[0], val=ca[1]) + id_l.append(cao.id) + for cao in DContainerArgs.objects.filter(container=co): + if (cao.id not in id_l): + cao.delete() + l_d = r_d.get('container_links', {}) for cname in l_d: ll = l_d[cname] diff --git a/src/rockstor/storageadmin/views/rockon_helpers.py b/src/rockstor/storageadmin/views/rockon_helpers.py index 5a6d48c50..b50d7a62f 100644 --- a/src/rockstor/storageadmin/views/rockon_helpers.py +++ b/src/rockstor/storageadmin/views/rockon_helpers.py @@ -26,7 +26,7 @@ from storageadmin.models import (RockOn, DContainer, DVolume, DPort, DCustomConfig, DContainerLink, ContainerOption, DContainerEnv, - DContainerDevice) + DContainerDevice, DContainerArgs) from fs.btrfs import mount_share from rockon_utils import container_status import logging @@ -206,6 +206,15 @@ def vol_owner_uid(container): return os.stat(share_mnt).st_uid +def cargs(container): + cargs_list = [] + for c in DContainerArgs.objects.filter(container=container): + cargs_list.append(c.name) + if (len(c.val.strip()) > 0): + cargs_list.append(c.val) + return cargs_list + + def envars(container): var_list = [] for e in DContainerEnv.objects.filter(container=container): @@ -233,6 +242,7 @@ def generic_install(rockon): cmd.extend(container_ops(c)) cmd.extend(envars(c)) cmd.append(c.dimage.name) + cmd.extend(cargs(c)) run_command(cmd)