Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

[RFC] another possibility for multiversion handling in 2.0 #136

Closed
Ma27 opened this issue Feb 27, 2016 · 0 comments
Closed

[RFC] another possibility for multiversion handling in 2.0 #136

Ma27 opened this issue Feb 27, 2016 · 0 comments

Comments

@Ma27
Copy link
Collaborator

Ma27 commented Feb 27, 2016

RFC for a new implementation of the nodejs install procedure

Status quo

The current approach has too many bugs and the approach of creating executables like nodejs-${version} is not supported by nodejs.

What does it do?

It installs into the /usr/local/node/node-${version} directory nodejs instances, supports old stuff like node v0.6 (which is not maintained for more than 2 years now) and creates links for any nodejs instance. NPM links should work, but are not implementable (see #94) and so on.
One of the first ideas was to use NVM for this kind of issue, but now I have my doubts since NVM would be just a wrapper of functionality for a job that can be done in a similar and better way with pure puppet. Furthermore I'm not a fan of forcing people to use fancy tools since a minority of users wishes to use a certain feature.

Another idea would be to rewrite the install process in puppet and keep proper support for most of the people having just one node instance, but provide a simple way to work with multiple instances on a machine which might be helpful when providing an application or library which has to support multiple nodejs versions.

How to do that?

Implementing a new define which is just responsible for downloading/removing (which is a refactored version of the heavy ::nodejs::install resource) could be used like this:

::nodejs::instance { 'node-v5.6':
  ensure => present,
  version => 'v5.6.0',
  from_source => true, # most of the users download it directly because it's faster, so the flag should be false by default
}

Removing an instance should look like this:

::nodejs::instance { 'node-v5.6':
  ensure => absent,
  version => 'v5.6.0',
}

The three parameters should be the only configuration options in order to keep the install process as simple as possible.
This should NOT affect any symlinks or executables, just adding or removing.

In the next step it should be possible to declare one instance as default one:

class { '::nodejs::default_instance':
  version => 'v5.6.0',
}

This step must be done after adding the instance because otherwise puppet should throw an error due to missing instances (no $require parameter should be necessary as this job should be taken by our nodejs module).
Currently we've got a nodejs.sh contained in the profile.d directory which affects the NODE_PATH and PATH variable. IMHO we can continue using this for exporting the NODE_PATH feature before further steps, but to provide one not-changing path for any node instance, the node and npm executable should be symlinked to /usr/local/bin.
In order to change one of those executables, puppet must be re-compiled. This is just like changing the environment in a server configuration or something like this since it is a complicated operation to change the default instance.

This module should tackle the containment of multiple instances, but should use one global default one to avoid dirty hacks. Also the machine should be rebuilt when testing on a machine an application against multiple instances.

Nodejs class

As the nodejs class is the entry point and responsible for the whole install process, the upper defines should be an implementation detail and raise a warning if called from elsewhere.

The nodejs class should get a hash containing the configs for single nodejs instances and delegate the setup job using the create_resources function. The second parameter should tell puppet which nodejs version must be the default one.

The nodejs whole setup could look like this when using hiera:

nodejs::instances:
  node-v5.6:
    version: v5.6.0
    from_source: true
  node-v0.12:
    version: v0.12.2

Now the default one must be set:

nodejs::default_instance: v5.6.0

Removing instances could look like this:

nodejs::instances:
  node-v5.6:
    version: v5.6.0
    ensure: absent

So adjusting the $ensure parameter can control whether to install or to remove an instance.

Why no nodenv

One of the key features of the version manager nodenv is that it is able to run multiple versions at the same time.

There are two things why I'm against using this:

Any usecases?

It is the same game as with nvm. A minority of people has a special case and want to have a certain tool and now I'd have to force people who just want to have an automated node setup to use such exaggregated technology.

There are certain cases where it is absolutly necessary to have multiple versions at the same time, but in the 1.x branch it was impossible to use the proper npm executable so such things didn't work at any time properly.

Furthermore one case - testing an application against multiple versions in a dev VM - can be done in 2.x by changing the active instance and would be rather easy in the new version.

Shim executables

Shim executables are a similar approach applied by nodenv to something I tried when attempting to fix the npm executables bug. The thing is that it is IMHO dirty hack to create faked executables to replace the actual executables for a program and look in it for the a suitable instance.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant