This post is to illustrate how we can use a generic package to deploy tgz packages.
Topics
- Overview and Motivation
- Generic Package
Overview and Motivation
It is very common to want to deploy a customization package that is based not on a full customization projects, but holds only some prepacked artifacts. For example when we want to use pre-release versions of product packages but don’t want to include the product source code in our project.
In this example I wanted to generate a deployable package outside of a project scaffolding. This example is mostly valid for Connect IoT / Factory Automation packages, but it can be tweaked for other type of artifacts.
Generic Package
Let’s first create our root package. A root package requires only the existence of a cmfpackage.json
that describes this as a root package. We will also add an entry to our package that will hold the tgz files.
{
"packageId": "Cmf.Custom.DeployTGZ",
"version": "1.0.0",
"description": "Package root for deploying TGZ",
"packageType": "Root",
"isInstallable": true,
"isUniqueInstall": false,
"dependencies": [
{
"id": "Cmf.Environment",
"version": "<%= $CLI_PARAM_MESVersion %>",
"mandatory": false
},
{
"id": "Cmf.Custom.DeployTGZ.Packages",
"version": "<%= $CLI_PARAM_MESVersion %>",
"mandatory": false
}
]
}
Now lets create a folder to hold our generic package. Let’s create a new cmfpackage.json
.
{
"packageId": "Cmf.Custom.DeployTGZ.Packages",
"version": "1.0.0",
"description": "Package to deploy TGZ",
"packageType": "Generic",
"isInstallable": true,
"isUniqueInstall": false,
"targetDirectory": "UI/Html",
"targetLayer": "ui",
"contentToPack": [
{
"source": "projects/*.tgz",
"target": "runtimePackages",
"ignoreFiles": [
".npmignore"
]
}
],
"xmlInjection": [
"steps.xml",
"ui.xml"
]
}
The generic package allows us to configure the build steps and steps to install as we wish. In this case we will not have build steps, but we will inject our deployment steps, in order to deploy the tgz files to the connect iot repository. The content to pack will dictate that the tgz files will be in the projects/
directory and will be deployed to a folder called runtimePackages. Then we will add a set of injectable steps, these will be joined and parsed to create the deployment metadata.
The ui xml will emulate the devops center options and steps in the GUI.
ui.xml:
<ui>
<wizardStep id="Deployment.ConnectIoT" order="100" title="IoT Configuration" type="generic" requiresValidation="true">
<groups>
<group id="Deployment.Steps.ConnectIoT.Directory" order="0" title="DIRECTORY REPOSITORY" type="generic" requiresValidation="false">
<variables>
<variable name="Local.Repository.Directory.Enabled" readOnly="false" isRequired="false" valueType="Boolean" label="Is Enabled" default="false" />
<variable name="Local.Repository.Directory.Location" readOnly="false" isRequired="false" valueType="Text" label="Location" placeholder="Example: C:\repositoryLocation" default="C:\repositoryLocation" />
</variables>
</group>
<group id="Deployment.Steps.ConnectIoT.Server" order="1" title="NPM SERVER REPOSITORY" type="generic" requiresValidation="false">
<variables>
<variable name="Local.Repository.Server.Enabled" readOnly="false" isRequired="false" valueType="Boolean" label="Is Enabled" default="false" />
<variable name="Local.Repository.Server.Address" readOnly="false" isRequired="false" valueType="Text" label="Address" placeholder="Example: http://127.0.0.1:4873" default="http://127.0.0.1:4873" />
<variable name="Publish.Tag" readOnly="false" isRequired="false" valueType="Text" label="Tag" placeholder="Example: latest" default="latest" />
<variable name="Local.Repository.Server.UserName" readOnly="false" isRequired="false" valueType="Text" label="Registry User" placeholder="Example: admin" default="admin" />
<variable name="Local.Repository.Server.UserPassword" readOnly="false" isRequired="false" valueType="Password" label="Registry User Password" placeholder="Example: password" default="password" />
<variable name="Local.Repository.Server.UserEmail" readOnly="false" isRequired="false" valueType="Text" label="Registry User Email" placeholder="Example: [email protected]" default="[email protected]" />
</variables>
</group>
</groups>
</wizardStep>
</ui>
The steps xml will be responsible to determine the actions to be performed. In this case we want not only to deploy but also to generate the repository index.
steps.xml:
<steps>
<!-- ONLY VALID For VM - Will be ignored in a container installation
<step type="DeployFiles" contentPath="runtimePackages/**" />
<step type="DeployFiles" contentPath="*.ps1" />
<step type="DeployFiles" contentPath="*.bat" />
<step type="Generic" onExecute="$(Package[Cmf.Custom.DeployTGZ.Packages].TargetDirectory)/runtimePackages/ValidateIoTInstall.ps1" />
<step type="Generic" onExecute="$(Package[Cmf.Custom.DeployTGZ.Packages].TargetDirectory)/runtimePackages/PublishToRepository.ps1" />
<step type="Generic" onExecute="$(Package[Cmf.Custom.DeployTGZ.Packages].TargetDirectory)/runtimePackages/PublishToDirectory.ps1" />
-->
<step type="DeployRepositoryFiles" contentPath="runtimePackages/**" />
<step type="GenerateRepositoryIndex" />
</steps>
Author
Hello 👏 , my name is João Roque ✌️
I’ve been working for some years at Critical Manufacturing. I split my time working in the IoT Team and working with the project’s teams. You can visit me at https://j-roque.com/ or check me at LinkedIn
Skills: Connect IoT / DevOps