Skip to content

Commit

Permalink
Deprecate the vscode tasks and create the devcontainer ones (#24573)
Browse files Browse the repository at this point in the history
* Deprecate the 'vscode' tasks and create the 'devcontainer' ones

* address

* lint

* Update tasks/vscode.py

* docs

* address
  • Loading branch information
FlorentClarret authored Apr 11, 2024
1 parent 23533d4 commit 06f114a
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 80 deletions.
5 changes: 4 additions & 1 deletion tasks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
cluster_agent_cloudfoundry,
components,
cws_instrumentation,
devcontainer,
diff,
docker_tasks,
docs,
Expand Down Expand Up @@ -71,7 +72,7 @@
send_unit_tests_stats,
test,
)
from tasks.install_tasks import download_tools, install_shellcheck, install_tools
from tasks.install_tasks import download_tools, install_devcontainer_cli, install_shellcheck, install_tools
from tasks.junit_tasks import junit_upload
from tasks.libs.common.go_workspaces import handle_go_work
from tasks.pr_checks import lint_releasenote
Expand Down Expand Up @@ -105,6 +106,7 @@
ns.add_task(print_default_build_tags)
ns.add_task(e2e_tests)
ns.add_task(install_shellcheck)
ns.add_task(install_devcontainer_cli)
ns.add_task(download_tools)
ns.add_task(install_tools)
ns.add_task(invoke_unit_tests)
Expand Down Expand Up @@ -160,6 +162,7 @@
ns.add_collection(owners)
ns.add_collection(modules)
ns.add_collection(pre_commit)
ns.add_collection(devcontainer)
ns.configure(
{
'run': {
Expand Down
168 changes: 168 additions & 0 deletions tasks/devcontainer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
"""
vscode namespaced tags
Helpers for getting vscode set up nicely
"""
import json
import os
from collections import OrderedDict
from pathlib import Path

from invoke import task
from invoke.exceptions import Exit
from libs.common.color import color_message

from tasks.build_tags import build_tags, filter_incompatible_tags, get_build_tags, get_default_build_tags
from tasks.flavor import AgentFlavor

DEVCONTAINER_DIR = ".devcontainer"
DEVCONTAINER_FILE = "devcontainer.json"
DEVCONTAINER_NAME = "datadog_agent_devcontainer"


@task
def setup(
_,
target="agent",
build_include=None,
build_exclude=None,
flavor=AgentFlavor.base.name,
arch='x64',
image='',
):
"""
Generate or Modify devcontainer settings file for this project.
"""
flavor = AgentFlavor[flavor]
if target not in build_tags[flavor]:
print("Must choose a valid target. Valid targets are: \n")
print(f'{", ".join(build_tags[flavor].keys())} \n')
return

build_include = (
get_default_build_tags(build=target, arch=arch, flavor=flavor)
if build_include is None
else filter_incompatible_tags(build_include.split(","), arch=arch)
)
build_exclude = [] if build_exclude is None else build_exclude.split(",")
use_tags = get_build_tags(build_include, build_exclude)

if not os.path.exists(DEVCONTAINER_DIR):
os.makedirs(DEVCONTAINER_DIR)

devcontainer = {}
fullpath = os.path.join(DEVCONTAINER_DIR, DEVCONTAINER_FILE)
if os.path.exists(fullpath):
with open(fullpath, "r") as sf:
devcontainer = json.load(sf, object_pairs_hook=OrderedDict)

local_build_tags = ",".join(use_tags)

devcontainer["name"] = "Datadog-Agent-DevEnv"
if image:
devcontainer["image"] = image
if devcontainer.get("build"):
del devcontainer["build"]
else:
devcontainer["build"] = {
"dockerfile": "Dockerfile",
"args": {},
}
if devcontainer.get("image"):
del devcontainer["image"]
devcontainer["runArgs"] = [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined",
"--name",
"datadog_agent_devcontainer",
]
devcontainer["remoteUser"] = "datadog"
devcontainer["mounts"] = ["source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind,consistency=cached"]
devcontainer["customizations"] = {
"vscode": {
"settings": {
"go.toolsManagement.checkForUpdates": "local",
"go.useLanguageServer": True,
"go.gopath": "/home/datadog/go",
"go.goroot": "/usr/local/go",
"go.buildTags": local_build_tags,
"go.testTags": local_build_tags,
"go.lintTool": "golangci-lint",
"go.lintOnSave": "file",
"go.lintFlags": [
"--build-tags",
local_build_tags,
"--config",
"/workspaces/datadog-agent/.golangci.yml",
],
"[go]": {
"editor.formatOnSave": True,
},
"gopls": {"formatting.local": "github.com/DataDog/datadog-agent"},
},
"extensions": ["golang.Go"],
}
}
devcontainer[
"postStartCommand"
] = "git config --global --add safe.directory /workspaces/datadog-agent && invoke install-tools && invoke deps"

with open(fullpath, "w") as sf:
json.dump(devcontainer, sf, indent=4, sort_keys=False, separators=(',', ': '))


@task
def start(ctx, path="."):
"""
Start the devcontainer
"""
if not file().exists():
print(color_message("No devcontainer settings found. Run `invoke devcontainer.setup` first.", "red"))
raise Exit(code=1)

if not is_installed(ctx):
print(color_message("Devcontainer CLI is not installed. Run `invoke install-devcontainer-cli` first.", "red"))
raise Exit(code=1)

ctx.run(f"devcontainer up --workspace-folder {path}")


@task
def stop(ctx):
"""
Stop the running devcontainer
"""
if not file().exists():
print(color_message("No devcontainer settings found. Run `inv devcontainer.setup` first and start it.", "red"))
raise Exit(code=1)

if not is_up(ctx):
print(color_message("Devcontainer is not running.", "red"))
raise Exit(code=1)

ctx.run(f"docker kill {DEVCONTAINER_NAME}")


@task
def restart(ctx, path="."):
"""
Restart the devcontainer
"""
ctx.run(f"docker rm -f {DEVCONTAINER_NAME}")
start(ctx, path)


def file() -> Path:
return Path(DEVCONTAINER_DIR) / DEVCONTAINER_FILE


def is_up(ctx) -> bool:
res = ctx.run("docker ps", hide=True, warn=True)
# TODO: it's fragile to just check for the container name, but it's the best we can do for now
return DEVCONTAINER_NAME in res.stdout


def is_installed(ctx) -> bool:
res = ctx.run("which devcontainer", hide=True, warn=True)
return res.ok
8 changes: 8 additions & 0 deletions tasks/install_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,11 @@ def install_shellcheck(ctx, version="0.8.0", destination="/usr/local/bin"):
)
ctx.run(f"cp \"/tmp/shellcheck-v{version}/shellcheck\" {destination}")
ctx.run(f"rm -rf \"/tmp/shellcheck-v{version}\"")


@task
def install_devcontainer_cli(ctx):
"""
Install the devcontainer CLI
"""
ctx.run("npm install -g @devcontainers/cli")
93 changes: 14 additions & 79 deletions tasks/vscode.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
"""
import json
import os
from collections import OrderedDict
from typing import OrderedDict

from invoke import task
from libs.common.color import color_message

from tasks.build_tags import build_tags, filter_incompatible_tags, get_build_tags, get_default_build_tags
from tasks.flavor import AgentFlavor

VSCODE_DIR = ".vscode"
VSCODE_FILE = "settings.json"
VSCODE_DEVCONTAINER_DIR = ".devcontainer"
VSCODE_DEVCONTAINER_FILE = "devcontainer.json"


@task
Expand Down Expand Up @@ -73,80 +72,16 @@ def setup_devcontainer(
"""
Generate or Modify devcontainer settings file for this project.
"""
flavor = AgentFlavor[flavor]
if target not in build_tags[flavor]:
print("Must choose a valid target. Valid targets are: \n")
print(f'{", ".join(build_tags[flavor].keys())} \n')
return

build_include = (
get_default_build_tags(build=target, arch=arch, flavor=flavor)
if build_include is None
else filter_incompatible_tags(build_include.split(","), arch=arch)
from tasks.devcontainer import setup

print(color_message('This command is deprecated, please use `devcontainer.setup` instead', "orange"))
print("Running `devcontainer.setup`...")
setup(
_,
target=target,
build_include=build_include,
build_exclude=build_exclude,
flavor=flavor,
arch=arch,
image=image,
)
build_exclude = [] if build_exclude is None else build_exclude.split(",")
use_tags = get_build_tags(build_include, build_exclude)

if not os.path.exists(VSCODE_DEVCONTAINER_DIR):
os.makedirs(VSCODE_DEVCONTAINER_DIR)

devcontainer = {}
fullpath = os.path.join(VSCODE_DEVCONTAINER_DIR, VSCODE_DEVCONTAINER_FILE)
if os.path.exists(fullpath):
with open(fullpath, "r") as sf:
devcontainer = json.load(sf, object_pairs_hook=OrderedDict)

local_build_tags = ",".join(use_tags)

devcontainer["name"] = "Datadog-Agent-DevEnv"
if image:
devcontainer["image"] = image
if devcontainer.get("build"):
del devcontainer["build"]
else:
devcontainer["build"] = {
"dockerfile": "Dockerfile",
"args": {},
}
if devcontainer.get("image"):
del devcontainer["image"]
devcontainer["runArgs"] = [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined",
"--name",
"datadog_agent_devcontainer",
]
devcontainer["remoteUser"] = "datadog"
devcontainer["mounts"] = ["source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind,consistency=cached"]
devcontainer["customizations"] = {
"vscode": {
"settings": {
"go.toolsManagement.checkForUpdates": "local",
"go.useLanguageServer": True,
"go.gopath": "/home/datadog/go",
"go.goroot": "/usr/local/go",
"go.buildTags": local_build_tags,
"go.testTags": local_build_tags,
"go.lintTool": "golangci-lint",
"go.lintOnSave": "file",
"go.lintFlags": [
"--build-tags",
local_build_tags,
"--config",
"/workspaces/datadog-agent/.golangci.yml",
],
"[go]": {
"editor.formatOnSave": True,
},
"gopls": {"formatting.local": "github.com/DataDog/datadog-agent"},
},
"extensions": ["golang.Go"],
}
}
devcontainer[
"postStartCommand"
] = "git config --global --add safe.directory /workspaces/datadog-agent && invoke install-tools && invoke deps"

with open(fullpath, "w") as sf:
json.dump(devcontainer, sf, indent=4, sort_keys=False, separators=(',', ': '))

0 comments on commit 06f114a

Please sign in to comment.