Skip to content
Merged
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
1 change: 1 addition & 0 deletions ddev/changelog.d/20353.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for Vagrant VMs in testing
2 changes: 1 addition & 1 deletion ddev/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,4 @@ ban-relative-imports = "parents"

[tool.ruff.lint.per-file-ignores]
#Tests can use assertions and relative imports
"**/tests/**/*" = ["I252"]
"**/tests/**/*" = ["I252"]
2 changes: 1 addition & 1 deletion ddev/src/ddev/cli/env/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def agent(app: Application, *, intg_name: str, environment: str, args: tuple[str

metadata = env_data.read_metadata()
agent_type = metadata.get(E2EMetadata.AGENT_TYPE, DEFAULT_AGENT_TYPE)
agent = get_agent_interface(agent_type)(app.platform, integration, environment, metadata, env_data.config_file)
agent = get_agent_interface(agent_type)(app, integration, environment, metadata, env_data.config_file)

full_args = list(args)
trigger_run = False
Expand Down
2 changes: 1 addition & 1 deletion ddev/src/ddev/cli/env/reload.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def reload_command(app: Application, *, intg_name: str, environment: str):

metadata = env_data.read_metadata()
agent_type = metadata.get(E2EMetadata.AGENT_TYPE, DEFAULT_AGENT_TYPE)
agent = get_agent_interface(agent_type)(app.platform, integration, environment, metadata, env_data.config_file)
agent = get_agent_interface(agent_type)(app, integration, environment, metadata, env_data.config_file)

try:
agent.restart()
Expand Down
2 changes: 1 addition & 1 deletion ddev/src/ddev/cli/env/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def shell(app: Application, *, intg_name: str, environment: str):

metadata = env_data.read_metadata()
agent_type = metadata.get(E2EMetadata.AGENT_TYPE, DEFAULT_AGENT_TYPE)
agent = get_agent_interface(agent_type)(app.platform, integration, environment, metadata, env_data.config_file)
agent = get_agent_interface(agent_type)(app, integration, environment, metadata, env_data.config_file)

try:
agent.enter_shell()
Expand Down
2 changes: 1 addition & 1 deletion ddev/src/ddev/cli/env/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def show(app: Application, *, intg_name: str | None, environment: str | None, fo

metadata = env_data.read_metadata()
agent_type = metadata.get(E2EMetadata.AGENT_TYPE, DEFAULT_AGENT_TYPE)
agent = get_agent_interface(agent_type)(app.platform, integration, environment, metadata, env_data.config_file)
agent = get_agent_interface(agent_type)(app, integration, environment, metadata, env_data.config_file)

app.display_pair('Agent type', agent_type)
app.display_pair('Agent ID', agent.get_id())
14 changes: 13 additions & 1 deletion ddev/src/ddev/cli/env/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@
# Licensed under a 3-clause BSD style license (see LICENSE)
from __future__ import annotations

# Configure logging level from DDEV_LOG_LEVEL environment variable
import logging
import os
from typing import TYPE_CHECKING

import click
from datadog_checks.dev.ci import running_on_ci

log_level_str = os.environ.get('DDEV_LOG_LEVEL', 'INFO').upper()
log_level = getattr(logging, log_level_str, logging.INFO)
logging.basicConfig(level=log_level, format='%(levelname)s: %(message)s')

if TYPE_CHECKING:
from ddev.cli.application import Application
Expand Down Expand Up @@ -136,7 +144,11 @@ def start(
env_data.write_config(config)

agent_type = metadata.get(E2EMetadata.AGENT_TYPE, DEFAULT_AGENT_TYPE)
agent = get_agent_interface(agent_type)(app.platform, integration, environment, metadata, env_data.config_file)

if agent_type == "vagrant" and running_on_ci():
app.abort(text="Vagrant is not supported on CI", code=0)

agent = get_agent_interface(agent_type)(app, integration, environment, metadata, env_data.config_file)

if not agent_build:
agent_build = (
Expand Down
2 changes: 1 addition & 1 deletion ddev/src/ddev/cli/env/stop.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def stop(app: Application, *, intg_name: str, environment: str, ignore_state: bo
env_vars.update(metadata.get(E2EMetadata.ENV_VARS, {}))

agent_type = metadata.get(E2EMetadata.AGENT_TYPE, DEFAULT_AGENT_TYPE)
agent = get_agent_interface(agent_type)(app.platform, integration, env, metadata, env_data.config_file)
agent = get_agent_interface(agent_type)(app, integration, env, metadata, env_data.config_file)

try:
agent.stop()
Expand Down
35 changes: 35 additions & 0 deletions ddev/src/ddev/e2e/agent/Vagrantfile.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :

$set_environment_variables = <<SCRIPT
tee "/etc/profile.d/myvars.sh" > "/dev/null" <<EOF

export LOCAL_IP=$(hostname -I | cut -d ' ' -f 1)
export DD_HOSTNAME=$(hostname)
{{ exported_env_vars_str }}

EOF
SCRIPT


Vagrant.configure("2") do |config|
config.vm.box = "{{ vagrant_box }}"
config.vm.box_version = "1.1"

{{ synced_folders_str | safe }}
config.vm.network "private_network", ip: "172.30.1.5"

config.vm.define "{{ vm_hostname }}" do |node|
node.vm.hostname = "{{ vm_hostname }}"

node.vm.provision "shell", inline: $set_environment_variables, run: "always"

node.vm.provision "shell", inline: <<-SHELL, run: "always"
sudo apt update
{{ agent_install_env_vars_str }} bash -c "$(curl -L https://install.datadoghq.com/scripts/install_script_agent7.sh)"
sudo service datadog-agent start && echo "Agent started successfully"
echo "VM {{ vm_hostname }} is ready"
SHELL
end

end
9 changes: 7 additions & 2 deletions ddev/src/ddev/e2e/agent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@


def get_agent_interface(agent_type: str) -> type[AgentInterface]:
if agent_type == 'docker':
if agent_type == "docker":
from ddev.e2e.agent.docker import DockerAgent

return DockerAgent

raise NotImplementedError(f'Unsupported Agent type: {agent_type}')
if agent_type == "vagrant":
from ddev.e2e.agent.vagrant import VagrantAgent

return VagrantAgent

raise NotImplementedError(f"Unsupported Agent type: {agent_type}")
13 changes: 13 additions & 0 deletions ddev/src/ddev/e2e/agent/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,16 @@ class AgentEnvVars:
SITE = 'DD_SITE'
TELEMETRY_ENABLED = 'DD_TELEMETRY_ENABLED'
URL = 'DD_DD_URL'


# Note: we cannot use pathlib to create the paths as the host running ddev might have a different OS than the VM's OS
# Agent file paths (Linux)
LINUX_AGENT_BIN_PATH = "/opt/datadog-agent/bin/agent/agent"
LINUX_AGENT_PYTHON_PREFIX = "/opt/datadog-agent/embedded/bin/python"
LINUX_AGENT_CONF_DIR = "/etc/datadog-agent/conf.d"
LINUX_SUDOERS_FILE_PATH = "/etc/sudoers.d/dd-agent"

# Agent file paths (Windows)
WINDOWS_AGENT_BIN_PATH = "C:\\Program Files\\Datadog\\Datadog Agent\\bin\\agent.exe"
WINDOWS_AGENT_PYTHON_PREFIX = "C:\\Program Files\\Datadog\\Datadog Agent\\embedded"
WINDOWS_AGENT_CONF_DIR = "C:\\ProgramData\\Datadog\\conf.d"
11 changes: 8 additions & 3 deletions ddev/src/ddev/e2e/agent/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,29 @@
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
from ddev.cli.application import Application
from ddev.integration.core import Integration
from ddev.utils.fs import Path
from ddev.utils.platform import Platform


class AgentInterface(ABC):
def __init__(
self, platform: Platform, integration: Integration, env: str, metadata: dict[str, Any], config_file: Path
self, app: Application, integration: Integration, env: str, metadata: dict[str, Any], config_file: Path
) -> None:
self.__platform = platform
self.__app = app
self.__integration = integration
self.__env = env
self.__metadata = metadata
self.__config_file = config_file

@property
def app(self) -> Application:
return self.__app

@property
def platform(self) -> Platform:
return self.__platform
return self.app.platform

@property
def integration(self) -> Integration:
Expand Down
Loading
Loading