etcher/lib/cli/unmount.js
Juan Cruz Viotti 6456a8fe96 upgrade: drivelist to v5.0.1 (#869)
- Fix internal SDCard reader descriptions in GNU/Linux.
- Transform `mountpoint` into an array of mountpoints.

Change-Type: patch
Changelog-Entry: Fix internal SDCard drive descriptions.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2016-11-16 13:52:20 +00:00

108 lines
3.0 KiB
JavaScript

/*
* Copyright 2016 resin.io
*
* 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.
*/
'use strict';
const _ = require('lodash');
const Bluebird = require('bluebird');
const childProcess = Bluebird.promisifyAll(require('child_process'));
const os = require('os');
/**
* @summary Unmount command templates
* @namespace COMMAND_TEMPLATES
* @private
*
* We make sure that the commands declared here exit
* successfully even if the drive is not mounted.
*/
const COMMAND_TEMPLATES = {
/**
* @property {String} darwin
* @memberof COMMAND_TEMPLATES
*/
darwin: '/usr/sbin/diskutil unmountDisk force <%= device %>',
/**
* @property {String} linux
* @memberof COMMAND_TEMPLATES
*
* @description
* If trying to unmount the raw device in Linux, we get:
* > umount: /dev/sdN: not mounted
* Therefore we use the ?* glob to make sure umount processes
* the partitions of sdN independently (even if they contain multiple digits)
* but not the raw device.
* We also redirect stderr to /dev/null to ignore warnings
* if a device is already unmounted.
* Finally, we also wrap the command in a boolean expression
* that always evaluates to true to ignore the return code,
* which is non zero when a device was already unmounted.
*/
linux: 'umount <%= device %>?* 2>/dev/null || /bin/true'
};
/**
* @summary Get UNIX unmount command
* @function
* @public
*
* @param {String} operatingSystem - operating system slug
* @param {Object} drive - drive object
* @returns {String} command
*
* @example
* const drivelist = require('drivelist');
* const os = require('os');
*
* drivelist.list((drives) => {
* const command = unmount.getUNIXUnmountCommand(os.platform(), drives[0]);
* });
*/
exports.getUNIXUnmountCommand = (operatingSystem, drive) => {
return _.template(COMMAND_TEMPLATES[operatingSystem])(drive);
};
/**
* @summary Unmount drive
* @function
* @public
*
* @param {Object} drive - drive object
* @returns {Promise}
*
* @example
* const Bluebird = require('bluebird');
* const drivelist = Bluebird.promisifyAll(require('drivelist'));
*
* drivelist.listAsync().each(unmount.unmountDrive);
*/
exports.unmountDrive = (drive) => {
const platform = os.platform();
if (platform === 'win32') {
const removedrive = Bluebird.promisifyAll(require('removedrive'));
return Bluebird.each(drive.mountpoints, (mountpoint) => {
return removedrive.ejectAsync(mountpoint.path);
});
}
const command = exports.getUNIXUnmountCommand(platform, drive);
return childProcess.execAsync(command);
};