Skip to content

Commit

Permalink
Update launch.json when adding modules (#262)
Browse files Browse the repository at this point in the history
* Scaffold solution from files instead of zip

* Update launch.js when adding modules

* Fix stuck on POSIX when adding node.js modules

* Adding template files to manifest.
  • Loading branch information
LazarusX authored and jongio committed Aug 16, 2018
1 parent 799faec commit d203829
Show file tree
Hide file tree
Showing 14 changed files with 385 additions and 27 deletions.
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
include HISTORY.rst
include LICENSE
include README.md
include iotedgedev/template/template.zip
include iotedgedev/monitor.js
include iotedgedev/template/*.*
recursive-include tests *
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
4 changes: 2 additions & 2 deletions iotedgedev/dockercls.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ def remove_images(self):
def handle_logs_cmd(self, show, save):

# Create LOGS_PATH dir if it doesn't exist
if save and not os.path.exists(self.envvars.LOGS_PATH):
os.makedirs(self.envvars.LOGS_PATH)
if save:
self.utility.ensure_dir(self.envvars.LOGS_PATH)

modules_in_config = self.utility.get_modules_in_config(ModuleType.Both)

Expand Down
58 changes: 54 additions & 4 deletions iotedgedev/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import re
import sys

import commentjson

from .deploymentmanifest import DeploymentManifest
from .dockercls import Docker
from .dotnet import DotNet
Expand All @@ -19,8 +21,7 @@ def add(self, name, template):
self.output.header("ADDING MODULE {0}".format(name))

cwd = self.envvars.MODULES_PATH
if not os.path.exists(cwd):
os.makedirs(cwd)
self.utility.ensure_dir(cwd)

if name.startswith("_") or name.endswith("_"):
self.output.error("Module name cannot start or end with the symbol _")
Expand All @@ -40,10 +41,11 @@ def add(self, name, template):
dotnet.install_module_template()
dotnet.create_custom_module(name, repo, cwd)
elif template == "nodejs":
self.utility.check_dependency("yo azure-iot-edge-module --help".split(), "To add new Node.js modules, the Yeoman tool and Azure IoT Edge Node.js module generator", shell=True)
self.utility.check_dependency("yo azure-iot-edge-module --help".split(), "To add new Node.js modules, the Yeoman tool and Azure IoT Edge Node.js module generator",
shell=not self.envvars.is_posix())
cmd = "yo azure-iot-edge-module -n {0} -r {1}".format(name, repo)
self.output.header(cmd)
self.utility.exe_proc(cmd.split(), shell=True, cwd=cwd)
self.utility.exe_proc(cmd.split(), shell=not self.envvars.is_posix(), cwd=cwd)
elif template == "python":
self.utility.check_dependency("cookiecutter --help".split(), "To add new Python modules, the Cookiecutter tool")
github_source = "https://github.com/Azure/cookiecutter-azure-iot-edge-module"
Expand All @@ -59,6 +61,8 @@ def add(self, name, template):
deployment_manifest.add_module_template(name)
deployment_manifest.save()

self._update_launch_json(name, template)

self.output.footer("ADD COMPLETE")

def build(self):
Expand Down Expand Up @@ -174,3 +178,49 @@ def filter_build_options(build_options):
filtered_build_options.append(build_option)

return filtered_build_options

def _update_launch_json(self, name, template):
new_launch_json = self._get_launch_json(name, template)
if new_launch_json is not None:
self._merge_launch_json(new_launch_json)

def _get_launch_json(self, name, template):
replacements = {}
replacements["%MODULE%"] = name
replacements["%MODULE_FOLDER%"] = name

launch_json_file = None
is_function = False
if template == "csharp":
launch_json_file = "launch_csharp.json"
replacements["%APP_FOLDER%"] = "/app"
elif template == "nodejs":
launch_json_file = "launch_node.json"
elif template == "csharpfunction":
launch_json_file = "launch_csharp.json"
replacements["%APP_FOLDER%"] = "/app"
is_function = True

if launch_json_file is not None:
launch_json_file = os.path.join(os.path.split(__file__)[0], "template", launch_json_file)
launch_json_content = self.utility.get_file_contents(launch_json_file)
for key, value in replacements.items():
launch_json_content = launch_json_content.replace(key, value)
launch_json = commentjson.loads(launch_json_content)
if is_function and launch_json is not None and "configurations" in launch_json:
# for Function modules, there shouldn't be launch config for local debug
launch_json["configurations"] = list(filter(lambda x: x["request"] != "launch", launch_json["configurations"]))
return launch_json

def _merge_launch_json(self, new_launch_json):
vscode_dir = os.path.join(os.getcwd(), ".vscode")
self.utility.ensure_dir(vscode_dir)
launch_json_file = os.path.join(vscode_dir, "launch.json")
if os.path.exists(launch_json_file):
launch_json = commentjson.loads(self.utility.get_file_contents(launch_json_file))
launch_json['configurations'].extend(new_launch_json['configurations'])
with open(launch_json_file, "w") as f:
commentjson.dump(launch_json, f, indent=2)
else:
with open(launch_json_file, "w") as f:
commentjson.dump(new_launch_json, f, indent=2)
17 changes: 4 additions & 13 deletions iotedgedev/solution.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import zipfile


class Solution:
Expand All @@ -19,19 +18,11 @@ def create(self, name, module, template):

self.output.header("CREATING AZURE IOT EDGE SOLUTION: {0}".format(name))

try:
template_zip = os.path.join(os.path.split(
__file__)[0], "template", "template.zip")
except Exception as ex:
self.output.error("Error while trying to load template.zip")
self.output.error(str(ex))
self.utility.ensure_dir(dir_path)

zipf = zipfile.ZipFile(template_zip)
zipf.extractall(name)

self.utility.copy_template(os.path.join(dir_path, "deployment.template.json"), None, {"%MODULE%": module}, False)

os.rename(os.path.join(name, ".env.tmp"), os.path.join(name, ".env"))
self.utility.copy_from_template_dir("deployment.template.json", dir_path, replacements={"%MODULE%": module})
self.utility.copy_from_template_dir(".gitignore", dir_path)
self.utility.copy_from_template_dir(".env.tmp", dir_path, dest_file=".env")

mod_cmd = "iotedgedev solution add {0} --template {1}".format(module, template)
self.output.header(mod_cmd)
Expand Down
43 changes: 43 additions & 0 deletions iotedgedev/template/launch_csharp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "%MODULE% Remote Debug (.NET Core)",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickRemoteProcess}",
"pipeTransport": {
"pipeProgram": "docker",
"pipeArgs": [
"exec",
"-i",
"%MODULE%",
"sh",
"-c"
],
"debuggerPath": "~/vsdbg/vsdbg",
"pipeCwd": "${workspaceFolder}",
"quoteArgs": true
},
"sourceFileMap": {
"%APP_FOLDER%": "${workspaceFolder}/modules/%MODULE_FOLDER%"
},
"justMyCode": true
},
{
"name": "%MODULE% Local Debug (.NET Core)",
"type": "coreclr",
"request": "launch",
"program": "${workspaceRoot}/modules/%MODULE_FOLDER%/bin/Debug/netcoreapp2.0/%MODULE%.dll",
"args": [],
"cwd": "${workspaceRoot}/modules/%MODULE_FOLDER%",
"internalConsoleOptions": "openOnSessionStart",
"stopAtEntry": false,
"console": "internalConsole",
"env": {
"EdgeHubConnectionString": "${config:azure-iot-edge.EdgeHubConnectionString}",
"EdgeModuleCACertificateFile": "${config:azure-iot-edge.EdgeModuleCACertificateFile}"
}
}
]
}
36 changes: 36 additions & 0 deletions iotedgedev/template/launch_node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "%MODULE% Remote Debug (Node.js)",
"type": "node",
"request": "attach",
"port": 9229,
"address": "localhost",
"localRoot": "${workspaceRoot}/modules/%MODULE_FOLDER%",
"remoteRoot": "/app",
"protocol": "inspector"
},
{
"name": "%MODULE% Remote Debug (Node.js in Windows Container)",
"type": "node",
"request": "attach",
"port": 9229,
"address": "localhost",
"localRoot": "${workspaceRoot}/modules/%MODULE_FOLDER%",
"remoteRoot": "C:\\app",
"protocol": "inspector"
},
{
"name": "%MODULE% Local Debug (Node.js)",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/modules/%MODULE_FOLDER%/app.js",
"console": "integratedTerminal",
"env": {
"EdgeHubConnectionString": "${config:azure-iot-edge.EdgeHubConnectionString}",
"EdgeModuleCACertificateFile": "${config:azure-iot-edge.EdgeModuleCACertificateFile}"
}
}
]
}
Binary file removed iotedgedev/template/template.zip
Binary file not shown.
15 changes: 12 additions & 3 deletions iotedgedev/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ def is_dir_empty(self, name):
else:
return True

def ensure_dir(self, name):
if not os.path.exists(name):
os.makedirs(name)

def find_files(self, directory, pattern):
# find all files in directory that match the pattern.
for root, dirs, files in os.walk(directory):
Expand Down Expand Up @@ -128,9 +132,7 @@ def set_config(self, force=False, replacements=None):
if not self.config_set or force:
self.output.header("PROCESSING CONFIG FILES")

# Create config dir if it doesn't exist
if not os.path.exists(self.envvars.CONFIG_OUTPUT_DIR):
os.makedirs(self.envvars.CONFIG_OUTPUT_DIR)
self.ensure_dir(self.envvars.CONFIG_OUTPUT_DIR)

config_files = self.get_config_files()

Expand All @@ -154,6 +156,13 @@ def set_config(self, force=False, replacements=None):

self.config_set = True

def copy_from_template_dir(self, src_file, dest_dir, dest_file=None, replacements=None):
if dest_file is None:
dest_file = src_file

template_dir = os.path.join(os.path.split(__file__)[0], "template")
self.copy_template(os.path.join(template_dir, src_file), os.path.join(dest_dir, dest_file), replacements, expandvars=False)

def copy_template(self, src, dest=None, replacements=None, expandvars=True):
"""Read file at src, replace the keys in replacements with their values, optionally expand environment variables, and save to dest"""
if dest is None:
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def run(self):
'azure-cli-configure',
'azure-cli-resource',
'azure-cli-cloud',
'iotedgehubdev'
'iotedgehubdev',
'commentjson'
]

setup_requirements = [
Expand Down
57 changes: 57 additions & 0 deletions tests/assets/deployment.template_4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"modulesContent": {
"$edgeAgent": {
"properties.desired": {
"schemaVersion": "1.0",
"runtime": {
"type": "docker",
"settings": {
"minDockerVersion": "v1.25",
"loggingOptions": ""
}
},
"systemModules": {
"edgeAgent": {
"type": "docker",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-agent:${RUNTIME_TAG}",
"createOptions": ""
}
},
"edgeHub": {
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-hub:${RUNTIME_TAG}",
"createOptions": "{\"HostConfig\":{\"PortBindings\":{\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
}
}
},
"modules": {
"tempSensor": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:${RUNTIME_TAG}",
"createOptions": ""
}
}
}
}
},
"$edgeHub": {
"properties.desired": {
"schemaVersion": "1.0",
"routes": {
"sensorTofiltermodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/input1\")"
},
"storeAndForwardConfiguration": {
"timeToLiveSecs": 7200
}
}
}
}
}
Loading

0 comments on commit d203829

Please sign in to comment.