Skip to content

Commit

Permalink
feat: Add node version selection heuristic to handle conditional Node…
Browse files Browse the repository at this point in the history
….JS version in package.json (#834)

* feat: Add node version selection heuristic to handle conditional Node.JS version in package.json

Signed-off-by: Akash Nayak <[email protected]>
Co-authored-by: Harikrishnan Balagopal <[email protected]>
  • Loading branch information
Akash-Nayak and HarikrishnanBalagopal authored Jul 28, 2022
1 parent 607d042 commit be8685d
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: move2kube.konveyor.io/v1alpha1
kind: NodeVersionsMapping
metadata:
name: NodeVersionsMapping
spec:
nodeVersions:
- "v16.16.0"
- "v14.20.0"
- "v12.22.12"
- "v10.24.1"
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

FROM registry.access.redhat.com/ubi8/nodejs-{{ .NodeVersion }}
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
RUN microdnf update && microdnf install wget xz tar && microdnf clean all && \
wget https://nodejs.org/dist/{{ .NodeVersion }}/node-{{ .NodeVersion }}-linux-x64.tar.xz && \
tar -xJf node-{{ .NodeVersion }}-linux-x64.tar.xz && \
mv node-{{ .NodeVersion }}-linux-x64 /node && \
rm -f node-{{ .NodeVersion }}-linux-x64.tar.xz
ENV PATH="$PATH:/node/bin"
COPY . .
RUN npm install
{{- if .Build }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ spec:
disabled: false
DockerfileForService:
disabled: false
config:
defaultNodejsVersion: "14"
externalFiles:
"../mappings/nodeversions.yaml" : mappings/nodeversions.yaml
1 change: 1 addition & 0 deletions assets/filepermissions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"built-in/transformers/dockerfilegenerator/java/waranalyser/transformer.yaml" : 0644
"built-in/transformers/dockerfilegenerator/java/warrouter/transformer.yaml" : 0644
"built-in/transformers/dockerfilegenerator/java/zuul/transformer.yaml" : 0644
"built-in/transformers/dockerfilegenerator/mappings/nodeversions.yaml" : 0644
"built-in/transformers/dockerfilegenerator/nodejs/templates/Dockerfile" : 0644
"built-in/transformers/dockerfilegenerator/nodejs/transformer.yaml" : 0644
"built-in/transformers/dockerfilegenerator/php/templates/Dockerfile" : 0644
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/go-git/go-git/v5 v5.4.2
github.com/google/go-cmp v0.5.7
github.com/gorilla/mux v1.8.0
github.com/hashicorp/go-version v1.6.0
github.com/joho/godotenv v1.4.0
github.com/magiconair/properties v1.8.5
github.com/mikefarah/yq/v4 v4.16.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,8 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
Expand Down
5 changes: 4 additions & 1 deletion samples/nodejs/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
"name" : "main",
"name" : "nodejs-webapp",
"version" : "0.1.0",
"description": "This is a test web server",
"keywords": ["test", "webserver"],
"engines": {
"node": "~>v14.10"
},
"scripts": {
"start": "node main.js"
}
Expand Down
59 changes: 42 additions & 17 deletions transformer/dockerfilegenerator/nodejsdockerfiletransformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,44 @@ package dockerfilegenerator
import (
"fmt"
"path/filepath"
"strings"

"github.com/joho/godotenv"
"github.com/konveyor/move2kube/common"
"github.com/konveyor/move2kube/environment"
"github.com/konveyor/move2kube/types"
irtypes "github.com/konveyor/move2kube/types/ir"
"github.com/konveyor/move2kube/types/qaengine/commonqa"
transformertypes "github.com/konveyor/move2kube/types/transformer"
"github.com/konveyor/move2kube/types/transformer/artifacts"

"github.com/sirupsen/logrus"
"github.com/spf13/cast"
"golang.org/x/mod/semver"
)

const (
defaultNodeVersion = "14"
packageJSONFile = "package.json"
packageJSONFile = "package.json"
versionMappingFilePath = "mappings/nodeversions.yaml"
// NodeVersionsMappingKind defines kind of NodeVersionMappingKind
NodeVersionsMappingKind types.Kind = "NodeVersionsMapping"
)

// NodeVersionsMapping stores the Node versions mapping
type NodeVersionsMapping struct {
types.TypeMeta `yaml:",inline"`
types.ObjectMeta `yaml:"metadata,omitempty"`
Spec NodeVersionsMappingSpec `yaml:"spec,omitempty"`
}

// NodeVersionsMappingSpec stores the Node version spec
type NodeVersionsMappingSpec struct {
NodeVersions []string `yaml:"nodeVersions"`
}

// NodejsDockerfileGenerator implements the Transformer interface
type NodejsDockerfileGenerator struct {
Config transformertypes.Transformer
Env *environment.Environment
NodejsConfig *NodejsDockerfileYamlConfig
NodeVersions []string
}

// NodejsTemplateConfig implements Nodejs config interface
Expand Down Expand Up @@ -86,9 +99,22 @@ func (t *NodejsDockerfileGenerator) Init(tc transformertypes.Transformer, env *e
logrus.Errorf("unable to load config for Transformer %+v into %T : %s", t.Config.Spec.Config, t.NodejsConfig, err)
return err
}
mappingFile := NodeVersionsMapping{}
mappingFilePath := filepath.Join(t.Env.GetEnvironmentContext(), versionMappingFilePath)
if err := common.ReadMove2KubeYaml(mappingFilePath, &mappingFile); err != nil {
return fmt.Errorf("failed to load the Node versions mapping file at path %s . Error: %q", mappingFilePath, err)
}
if len(mappingFile.Spec.NodeVersions) == 0 {
return fmt.Errorf("the mapping file at path %s is invalid", mappingFilePath)
}
t.NodeVersions = mappingFile.Spec.NodeVersions
if len(t.NodeVersions) == 0 {
return fmt.Errorf("atleast one node version should be specified in the nodeversions mappings file- %s", mappingFilePath)
}
if t.NodejsConfig.DefaultNodejsVersion == "" {
t.NodejsConfig.DefaultNodejsVersion = defaultNodeVersion
t.NodejsConfig.DefaultNodejsVersion = t.NodeVersions[0]
}
logrus.Debugf("Extracted node versions from nodeversion mappings file - %+v", t.NodeVersions)
return nil
}

Expand Down Expand Up @@ -149,19 +175,18 @@ func (t *NodejsDockerfileGenerator) Transform(newArtifacts []transformertypes.Ar
var nodeVersion string
var packageJSON PackageJSON
if err := common.ReadJSON(filepath.Join(a.Paths[artifacts.ServiceDirPathType][0], packageJSONFile), &packageJSON); err != nil {
logrus.Debugf("unable to read the package.json file: %s", err)
} else {
if _, ok := packageJSON.Scripts["build"]; ok {
build = true
}
if node, ok := packageJSON.Engines["node"]; ok {
if !strings.HasPrefix(node, "v") {
node = "v" + node
}
nodeVersion = strings.TrimPrefix(semver.Major(node), "v")
}
logrus.Errorf("unable to read the package.json file: %s", err)
continue
}
if _, ok := packageJSON.Scripts["build"]; ok {
build = true
}
if nodeVersionConstraint, ok := packageJSON.Engines["node"]; ok {
nodeVersion = getNodeVersion(nodeVersionConstraint, t.NodejsConfig.DefaultNodejsVersion, t.NodeVersions)
logrus.Debugf("Selected nodeVersion is - %s", nodeVersion)
}
if nodeVersion == "" {
logrus.Infof("No Node version specified in the package.json file. Selecting the default Node version- %s", t.NodejsConfig.DefaultNodejsVersion)
nodeVersion = t.NodejsConfig.DefaultNodejsVersion
}
ports := ir.GetAllServicePorts()
Expand Down
46 changes: 46 additions & 0 deletions transformer/dockerfilegenerator/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright IBM Corporation 2021
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dockerfilegenerator

import (
"github.com/hashicorp/go-version"
"github.com/sirupsen/logrus"
)

// getNodeVersion returns the Node version to be used for the service
func getNodeVersion(versionConstraint, defaultNodejsVersion string, supportedVersions []string) string {
v1, err := version.NewVersion(versionConstraint)
if err == nil {
logrus.Debugf("the constraint is a Node version: %#v", v1)
return "v" + v1.String()
}
constraints, err := version.NewConstraint(versionConstraint)
if err != nil {
logrus.Errorf("failed to parse the Node version constraint string. Error: %q Actual: %s", err, versionConstraint)
return defaultNodejsVersion
}
logrus.Debugf("Node version constraints len = %d; constraints = %#v", constraints.Len(), constraints.String())
for _, supportedVersion := range supportedVersions {
ver, _ := version.NewVersion(supportedVersion)
if constraints.Check(ver) {
logrus.Debugf("%#v satisfies constraints %#v\n", ver, constraints)
return supportedVersion
}
}
logrus.Infof("no supported Node version detected in package.json. Selecting default Node version- %s", defaultNodejsVersion)
return defaultNodejsVersion
}

0 comments on commit be8685d

Please sign in to comment.