Add support for networks data in Standalone
Standalone does not use any of the composable networks by default. Deploy Standaloen using /dev/null as network data so that these resources are not included when creating the plan. Undercloud uses only the External network for the external VIP. Deploy the undercloud using the Undercloud specific network_data_undercloud.yaml, ensures external_from_pool.yaml is in the plan. Related-Bug: #1809313 Depends-On: Ib11a134df93e59947168b40bc71fb1da9172d4ac Change-Id: I102912851a3b9952daaf7c4d5a34a919f527f805
This commit is contained in:
parent
e484c48764
commit
51ad17ba18
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Standalone deployment now support for custom networks data
|
||||||
|
(``network_data.yaml``). By default Standalone deploys with no networks
|
||||||
|
data (all services on the ctlplane network). The new option
|
||||||
|
``networks_file`` can be used to provide custom networks data.
|
@ -155,6 +155,12 @@ class StandaloneConfig(BaseConfig):
|
|||||||
'absolute path or the path relative to the '
|
'absolute path or the path relative to the '
|
||||||
't-h-t templates directory used for deployment')
|
't-h-t templates directory used for deployment')
|
||||||
),
|
),
|
||||||
|
cfg.StrOpt('networks_file',
|
||||||
|
default=None,
|
||||||
|
help=_('Networks file to override for heat. May be an '
|
||||||
|
'absolute path or the path relative to the '
|
||||||
|
't-h-t templates directory used for deployment')
|
||||||
|
),
|
||||||
cfg.BoolOpt('heat_native',
|
cfg.BoolOpt('heat_native',
|
||||||
default=True,
|
default=True,
|
||||||
help=_('Execute the heat-all process natively on this '
|
help=_('Execute the heat-all process natively on this '
|
||||||
|
@ -24,6 +24,8 @@ STANDALONE_EPHEMERAL_STACK_VSTATE = '/var/lib/tripleo-heat-installer'
|
|||||||
UNDERCLOUD_LOG_FILE = "install-undercloud.log"
|
UNDERCLOUD_LOG_FILE = "install-undercloud.log"
|
||||||
UNDERCLOUD_CONF_PATH = os.path.join(UNDERCLOUD_OUTPUT_DIR, "undercloud.conf")
|
UNDERCLOUD_CONF_PATH = os.path.join(UNDERCLOUD_OUTPUT_DIR, "undercloud.conf")
|
||||||
OVERCLOUD_NETWORKS_FILE = "network_data.yaml"
|
OVERCLOUD_NETWORKS_FILE = "network_data.yaml"
|
||||||
|
STANDALONE_NETWORKS_FILE = "/dev/null"
|
||||||
|
UNDERCLOUD_NETWORKS_FILE = "network_data_undercloud.yaml"
|
||||||
RHEL_REGISTRATION_EXTRACONFIG_NAME = (
|
RHEL_REGISTRATION_EXTRACONFIG_NAME = (
|
||||||
"extraconfig/pre_deploy/rhel-registration/")
|
"extraconfig/pre_deploy/rhel-registration/")
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ class TestStandaloneConfig(base.TestCase):
|
|||||||
'heat_native',
|
'heat_native',
|
||||||
'hieradata_override',
|
'hieradata_override',
|
||||||
'net_config_override',
|
'net_config_override',
|
||||||
|
'networks_file',
|
||||||
'output_dir',
|
'output_dir',
|
||||||
'roles_file',
|
'roles_file',
|
||||||
'templates']
|
'templates']
|
||||||
@ -105,6 +106,7 @@ class TestStandaloneConfig(base.TestCase):
|
|||||||
'heat_native',
|
'heat_native',
|
||||||
'hieradata_override',
|
'hieradata_override',
|
||||||
'net_config_override',
|
'net_config_override',
|
||||||
|
'networks_file',
|
||||||
'output_dir',
|
'output_dir',
|
||||||
'roles_file',
|
'roles_file',
|
||||||
'templates']
|
'templates']
|
||||||
|
@ -55,6 +55,7 @@ class TestUndercloudConfig(base.TestCase):
|
|||||||
'local_mtu',
|
'local_mtu',
|
||||||
'local_subnet',
|
'local_subnet',
|
||||||
'net_config_override',
|
'net_config_override',
|
||||||
|
'networks_file',
|
||||||
'output_dir',
|
'output_dir',
|
||||||
'overcloud_domain_name',
|
'overcloud_domain_name',
|
||||||
'roles_file',
|
'roles_file',
|
||||||
@ -118,6 +119,7 @@ class TestUndercloudConfig(base.TestCase):
|
|||||||
'local_mtu',
|
'local_mtu',
|
||||||
'local_subnet',
|
'local_subnet',
|
||||||
'net_config_override',
|
'net_config_override',
|
||||||
|
'networks_file',
|
||||||
'output_dir',
|
'output_dir',
|
||||||
'overcloud_domain_name',
|
'overcloud_domain_name',
|
||||||
'roles_file',
|
'roles_file',
|
||||||
|
@ -91,6 +91,29 @@ class TestDeployUndercloud(TestPluginV1):
|
|||||||
self.assertEqual(roles_file,
|
self.assertEqual(roles_file,
|
||||||
'/tmp/thtroot/roles_data_undercloud.yaml')
|
'/tmp/thtroot/roles_data_undercloud.yaml')
|
||||||
|
|
||||||
|
def test_get_networks_file_path(self):
|
||||||
|
parsed_args = self.check_parser(self.cmd,
|
||||||
|
['--local-ip', '127.0.0.1/8'], [])
|
||||||
|
|
||||||
|
networks_file = self.cmd._get_networks_file_path(parsed_args)
|
||||||
|
self.assertEqual('/dev/null', networks_file)
|
||||||
|
|
||||||
|
def test_get_networks_file_path_custom_file(self):
|
||||||
|
parsed_args = self.check_parser(self.cmd,
|
||||||
|
['--local-ip', '127.0.0.1/8',
|
||||||
|
'--networks-file', 'foobar.yaml'], [])
|
||||||
|
|
||||||
|
networks_file = self.cmd._get_networks_file_path(parsed_args)
|
||||||
|
self.assertEqual('foobar.yaml', networks_file)
|
||||||
|
|
||||||
|
def test_get_networks_file_path_custom_templates(self):
|
||||||
|
parsed_args = self.check_parser(self.cmd,
|
||||||
|
['--local-ip', '127.0.0.1/8',
|
||||||
|
'--templates', '/tmp/thtroot'], [])
|
||||||
|
|
||||||
|
networks_file = self.cmd._get_networks_file_path(parsed_args)
|
||||||
|
self.assertEqual('/dev/null', networks_file)
|
||||||
|
|
||||||
def test_get_plan_env_file_path(self):
|
def test_get_plan_env_file_path(self):
|
||||||
parsed_args = self.check_parser(self.cmd,
|
parsed_args = self.check_parser(self.cmd,
|
||||||
['--local-ip', '127.0.0.1/8'], [])
|
['--local-ip', '127.0.0.1/8'], [])
|
||||||
@ -575,8 +598,8 @@ class TestDeployUndercloud(TestPluginV1):
|
|||||||
self.cmd.output_dir = 'tht_to'
|
self.cmd.output_dir = 'tht_to'
|
||||||
self.cmd.tht_render = 'tht_from'
|
self.cmd.tht_render = 'tht_from'
|
||||||
self.cmd.stack_action = 'UPDATE'
|
self.cmd.stack_action = 'UPDATE'
|
||||||
environment = self.cmd._setup_heat_environments(parsed_args.roles_file,
|
environment = self.cmd._setup_heat_environments(
|
||||||
parsed_args)
|
parsed_args.roles_file, parsed_args.networks_file, parsed_args)
|
||||||
|
|
||||||
self.assertIn(dropin, environment)
|
self.assertIn(dropin, environment)
|
||||||
mock_open.assert_has_calls([mock.call(dropin, 'w')])
|
mock_open.assert_has_calls([mock.call(dropin, 'w')])
|
||||||
@ -746,7 +769,8 @@ class TestDeployUndercloud(TestPluginV1):
|
|||||||
with mock.patch('os.path.abspath', side_effect=abs_path_stub):
|
with mock.patch('os.path.abspath', side_effect=abs_path_stub):
|
||||||
with mock.patch('os.path.isfile'):
|
with mock.patch('os.path.isfile'):
|
||||||
environment = self.cmd._setup_heat_environments(
|
environment = self.cmd._setup_heat_environments(
|
||||||
parsed_args.roles_file, parsed_args)
|
parsed_args.roles_file, parsed_args.networks_file,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
self.assertEqual(expected_env, environment)
|
self.assertEqual(expected_env, environment)
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ class TestUndercloudInstall(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--heat-native', '-e',
|
'--heat-native', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'undercloud.yaml', '-e',
|
'undercloud.yaml', '-e',
|
||||||
@ -144,6 +145,7 @@ class TestUndercloudInstall(TestPluginV1):
|
|||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usertht',
|
'--templates=/usertht',
|
||||||
'--roles-file=foo/roles.yaml',
|
'--roles-file=foo/roles.yaml',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--heat-native=False', '-e',
|
'--heat-native=False', '-e',
|
||||||
'/usertht/environments/undercloud.yaml', '-e',
|
'/usertht/environments/undercloud.yaml', '-e',
|
||||||
'/usertht/environments/use-dns-for-vips.yaml', '-e',
|
'/usertht/environments/use-dns-for-vips.yaml', '-e',
|
||||||
@ -295,6 +297,7 @@ class TestUndercloudInstall(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--heat-native', '-e',
|
'--heat-native', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'undercloud.yaml', '-e',
|
'undercloud.yaml', '-e',
|
||||||
@ -364,6 +367,7 @@ class TestUndercloudInstall(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--heat-native', '-e',
|
'--heat-native', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'undercloud.yaml', '-e',
|
'undercloud.yaml', '-e',
|
||||||
@ -426,6 +430,7 @@ class TestUndercloudInstall(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--heat-native', '-e',
|
'--heat-native', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'undercloud.yaml', '-e',
|
'undercloud.yaml', '-e',
|
||||||
@ -485,6 +490,7 @@ class TestUndercloudInstall(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--heat-native', '-e',
|
'--heat-native', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'undercloud.yaml', '-e',
|
'undercloud.yaml', '-e',
|
||||||
@ -563,6 +569,7 @@ class TestUndercloudUpgrade(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--upgrade', '-e',
|
'--upgrade', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'lifecycle/undercloud-upgrade-prepare.yaml',
|
'lifecycle/undercloud-upgrade-prepare.yaml',
|
||||||
@ -625,6 +632,7 @@ class TestUndercloudUpgrade(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--upgrade', '-e',
|
'--upgrade', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'lifecycle/undercloud-upgrade-prepare.yaml',
|
'lifecycle/undercloud-upgrade-prepare.yaml',
|
||||||
@ -686,6 +694,7 @@ class TestUndercloudUpgrade(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--upgrade', '-e',
|
'--upgrade', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'lifecycle/undercloud-upgrade-prepare.yaml',
|
'lifecycle/undercloud-upgrade-prepare.yaml',
|
||||||
@ -747,6 +756,7 @@ class TestUndercloudUpgrade(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'-y', '--upgrade', '-e',
|
'-y', '--upgrade', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'lifecycle/undercloud-upgrade-prepare.yaml',
|
'lifecycle/undercloud-upgrade-prepare.yaml',
|
||||||
@ -812,6 +822,7 @@ class TestUndercloudUpgrade(TestPluginV1):
|
|||||||
'--local-domain=localdomain',
|
'--local-domain=localdomain',
|
||||||
'--local-ip=192.168.24.1/24',
|
'--local-ip=192.168.24.1/24',
|
||||||
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
'--templates=/usr/share/openstack-tripleo-heat-templates/',
|
||||||
|
'--networks-file=network_data_undercloud.yaml',
|
||||||
'--upgrade', '-e',
|
'--upgrade', '-e',
|
||||||
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
'/usr/share/openstack-tripleo-heat-templates/environments/'
|
||||||
'lifecycle/undercloud-upgrade-prepare.yaml',
|
'lifecycle/undercloud-upgrade-prepare.yaml',
|
||||||
|
@ -162,6 +162,14 @@ class Deploy(command.Command):
|
|||||||
roles_file = parsed_args.roles_file
|
roles_file = parsed_args.roles_file
|
||||||
return roles_file
|
return roles_file
|
||||||
|
|
||||||
|
def _get_networks_file_path(self, parsed_args):
|
||||||
|
"""Return networks_file for the deployment"""
|
||||||
|
if not parsed_args.networks_file:
|
||||||
|
return os.path.join(parsed_args.templates,
|
||||||
|
constants.STANDALONE_NETWORKS_FILE)
|
||||||
|
else:
|
||||||
|
return parsed_args.networks_file
|
||||||
|
|
||||||
def _get_plan_env_file_path(self, parsed_args):
|
def _get_plan_env_file_path(self, parsed_args):
|
||||||
"""Return plan_environment_file for the deployment"""
|
"""Return plan_environment_file for the deployment"""
|
||||||
if not parsed_args.plan_environment_file:
|
if not parsed_args.plan_environment_file:
|
||||||
@ -582,7 +590,8 @@ class Deploy(command.Command):
|
|||||||
environments.append(target_dest)
|
environments.append(target_dest)
|
||||||
return environments
|
return environments
|
||||||
|
|
||||||
def _setup_heat_environments(self, roles_file_path, parsed_args):
|
def _setup_heat_environments(self, roles_file_path, networks_file_path,
|
||||||
|
parsed_args):
|
||||||
"""Process tripleo heat templates with jinja and deploy into work dir
|
"""Process tripleo heat templates with jinja and deploy into work dir
|
||||||
|
|
||||||
* Process j2/install additional templates there
|
* Process j2/install additional templates there
|
||||||
@ -611,7 +620,8 @@ class Deploy(command.Command):
|
|||||||
process_templates = os.path.join(parsed_args.templates,
|
process_templates = os.path.join(parsed_args.templates,
|
||||||
'tools/process-templates.py')
|
'tools/process-templates.py')
|
||||||
args = [self.python_cmd, process_templates, '--roles-data',
|
args = [self.python_cmd, process_templates, '--roles-data',
|
||||||
roles_file_path, '--output-dir', self.tht_render]
|
roles_file_path, '--network-data', networks_file_path,
|
||||||
|
'--output-dir', self.tht_render]
|
||||||
if utils.run_command_and_log(self.log, args, cwd=self.tht_render) != 0:
|
if utils.run_command_and_log(self.log, args, cwd=self.tht_render) != 0:
|
||||||
# TODO(aschultz): improve error messaging
|
# TODO(aschultz): improve error messaging
|
||||||
msg = _("Problems generating templates.")
|
msg = _("Problems generating templates.")
|
||||||
@ -718,10 +728,11 @@ class Deploy(command.Command):
|
|||||||
parsed_args):
|
parsed_args):
|
||||||
"""Deploy the fixed templates in TripleO Heat Templates"""
|
"""Deploy the fixed templates in TripleO Heat Templates"""
|
||||||
roles_file_path = self._get_roles_file_path(parsed_args)
|
roles_file_path = self._get_roles_file_path(parsed_args)
|
||||||
|
networks_file_path = self._get_networks_file_path(parsed_args)
|
||||||
|
|
||||||
# sets self.tht_render to the working dir with deployed templates
|
# sets self.tht_render to the working dir with deployed templates
|
||||||
environments = self._setup_heat_environments(
|
environments = self._setup_heat_environments(
|
||||||
roles_file_path, parsed_args)
|
roles_file_path, networks_file_path, parsed_args)
|
||||||
|
|
||||||
# rewrite paths to consume t-h-t env files from the working dir
|
# rewrite paths to consume t-h-t env files from the working dir
|
||||||
self.log.debug(_("Processing environment files %s") % environments)
|
self.log.debug(_("Processing environment files %s") % environments)
|
||||||
@ -753,7 +764,7 @@ class Deploy(command.Command):
|
|||||||
f.write(yaml.safe_dump(roles_data))
|
f.write(yaml.safe_dump(roles_data))
|
||||||
# Redo the dance
|
# Redo the dance
|
||||||
environments = self._setup_heat_environments(
|
environments = self._setup_heat_environments(
|
||||||
roles_file_path, parsed_args)
|
roles_file_path, networks_file_path, parsed_args)
|
||||||
env_files, env = utils.process_multiple_environments(
|
env_files, env = utils.process_multiple_environments(
|
||||||
environments, self.tht_render, parsed_args.templates,
|
environments, self.tht_render, parsed_args.templates,
|
||||||
cleanup=parsed_args.cleanup)
|
cleanup=parsed_args.cleanup)
|
||||||
@ -920,6 +931,14 @@ class Deploy(command.Command):
|
|||||||
'absolute path or the path relative to the templates dir.'
|
'absolute path or the path relative to the templates dir.'
|
||||||
) % constants.UNDERCLOUD_ROLES_FILE
|
) % constants.UNDERCLOUD_ROLES_FILE
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--networks-file', '-n', dest='networks_file',
|
||||||
|
help=_(
|
||||||
|
'Roles file, overrides the default %s in the t-h-t templates '
|
||||||
|
'directory used for deployment. May be an '
|
||||||
|
'absolute path or the path relative to the templates dir.'
|
||||||
|
) % constants.STANDALONE_NETWORKS_FILE
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--plan-environment-file', '-p',
|
'--plan-environment-file', '-p',
|
||||||
help=_('Plan Environment file, overrides the default %s in the '
|
help=_('Plan Environment file, overrides the default %s in the '
|
||||||
|
@ -426,6 +426,12 @@ def prepare_undercloud_deploy(upgrade=False, no_validations=False,
|
|||||||
if CONF.get('roles_file', constants.UNDERCLOUD_ROLES_FILE):
|
if CONF.get('roles_file', constants.UNDERCLOUD_ROLES_FILE):
|
||||||
deploy_args.append('--roles-file=%s' % CONF['roles_file'])
|
deploy_args.append('--roles-file=%s' % CONF['roles_file'])
|
||||||
|
|
||||||
|
if CONF.get('networks_file'):
|
||||||
|
deploy_args.append('--networks-file=%s' % CONF['networks_file'])
|
||||||
|
else:
|
||||||
|
deploy_args.append('--networks-file=%s' %
|
||||||
|
constants.UNDERCLOUD_NETWORKS_FILE)
|
||||||
|
|
||||||
if yes:
|
if yes:
|
||||||
deploy_args += ['-y']
|
deploy_args += ['-y']
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user