This escapes the diskpart script filename when shelling out,
to avoid failure when the username and thus the `os.tmpdir()` path
contains spaces.
Change-Type: patch
This reverts commit 47fc1b7357bdb9e9aa8e2d7476690435087d984e
in order to prevent a possible regression, until properly investigated
and fixed.
Change-Type: patch
Changelog-Entry: Revert using native binding to clean disks on Windows
This fixes the use and handling of events in the write pipeline,
such that the pipeline would not be prematurely stalled or terminated.
Also, a new `fail` event is introduced, to signal non-fatal errors.
Change-Type: patch
Implement writing to multiple destinations simultaneously
Change-Type: minor
Changelog-Entry: Implement writing to multiple destinations simultaneously
As crc32-stream was identified as a massive performance bottleneck,
we remove it, and default to Node's crypto API with md5 instead.
Change-Type: minor
This moves the preparation logic from the CLI into the SDK
in preparation for further SDK rearchitecturing, and to allow
standalone usage of SDK.
Change-Type: minor
Changelog-Entry: Move CLI write preparation logic into SDK
This removes O_DIRECT and O_EXCL flags from the writer,
as O_DIRECT can lead to EINVAL under quite a few circumstances,
and O_EXCL has proven to be useless.
Change-Type: patch
This replaces shelling out to `diskpart` on Windows to clear
the partition table with `win-drive-clean`, which does so via DeviceIoControl.
Change-Type: minor
Changelog-Entry: Use native code to clean drives on Windows
We replace the lodash templates with arrow-functions and change the
single-argument object into multiple arguments.
Fixes#1810Closes#2006
Change-Type: patch
Changelog-Entry: Replace Lodash templates with arrow-functions.
Etcher currently elevates a child writer proxy that itself spawns the
Etcher CLI in robot mode, parses the output, and proxies those messages
to the GUI application over IPC.
After these set of changes, Etcher elevates a single child writer
process that directly communicates back with the GUI using IPC. The main
purpose behind these changes is to simplify the overall architecture and
fix various issues caused by the current complex child process tree.
Here's a summary of the changes:
- Stop wrapping the Etcher CLI to perform writing
- Remove the robot option from the Etcher CLI (along with related
documentation)
- Elevate a new `child-write.js` standalone executable
- Move the relevant bits of `lib/child-writer` to the `image-writer` GUI
module
- Remove the `lib/child-writer` directory
- Add a new "Child died unexpectedly" Mixpanel event
- Floor state percentage in the flash state model
The above changes made is possible to tackle all the remaining issues
where the writer process would remain alive even if the parent died.
Change-Type: patch
Changelog-Entry: Ensure the writer process dies when the GUI application is killed.
See: https://github.com/resin-io/etcher/pull/1873
See: https://github.com/resin-io/etcher/pull/1843
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
We change from using `rs+` to a composition of read/write,
exlusive, sync & direct i/o flags, in order to avoid reading
stale data from the cache during verification.
Change-Type: patch
Changelog-Entry: Fix verification step reading from the cache
This implements a new way of image write streaming under use of pipage and blockmap, which paves the way for a few things like using network locations as sources, and imaging of storage devices (aka backups). As it allows for mutation of the streaming pipeline while it's writing, it also facilitates the development of dynamic block-mapping.
Change-Type: minor
- Extend the `standard` ESLint configuration
- Remove ESLint rules that are defined in the `standard` configuration
- Get rid of semi-colons
See: https://github.com/resin-io/etcher/pull/1657
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This commit changes the whole codebase to adhere to all StandardJS
guidelines rules except semicolons, since the removal of semicolons
affect pretty much all lines, and the final diff is very hard to follow
(and to assess other more involved changes).
In a nutshell:
- When using `function`, we now require a space before the opening
parenthesis
- If a line with operators is broken into multiple lines, the operator
should now go after the line break
- Unnecessary padding lines are now forbidden
There were also some minor things that the `standard` CLI caught that I
updated here.
See: https://standardjs.com
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
The `flashComplete` message takes the drive object and the image
basename as arguments. This was updated on the GUI, but causes the CLI
to throw an error upon completion.
Change-Type: patch
Changelog-Entry: Fix "imageBasename is not defined" error on the CLI.
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
If the user has the "Unmount on success" setting enabled, then Etcher
will unmount the drive after ther flashing process completed, right
after closing the drive file descriptor.
Turns out macOS will attempt to re-mount a drive once its file
descriptor gets closed, which means that if we try to unmount too fast,
then the drive will get re-mounted again.
As a naive solution, we add a timeout before finally unmounting the
drive. Keep in the mind this is only a temporary solution until we fix
mountutils to do the right thing.
See: https://github.com/resin-io/etcher/pull/1414
Fixes: https://github.com/resin-io/etcher/issues/1385
Change-Type: patch
Changelog-Entry: Prevent drive from getting re-mounted in macOS even when the unmount on success setting is enabled.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
Currently, both of these functions accept two arguments: the error
title, and the error description. This function signature makes is hard
to keep adding options to these error creation functions, like an error
code, so this commit refactors them to take a single argument: an
options object containing `title` and `description` properties.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
Windows will not react to dynamically set environment variables (e.g:
`process.env.MOUNTUTILS_DEBUG = '1'`), so in order to workaround this
limitation, we set `MOUNTUTILS_DEBUG` in
`lib/child-writer/writer-proxy.js` when spawning the CLI, and we also
set `DEBUG='*'` in `lib/start.js`, so it gets picked up by the child
writer module, which spawns the writer proxy by inheriting the
environment.
This version accepts a `MOUNTUTILS_DEBUG` environment variable to make
the module output extra logging information, which we enable in this
commit as well.
See: https://github.com/resin-io-modules/mountutils/pull/25
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
Consider the following scenario:
- The user selects an image from an external drive
- The user selects a drive
- The user unmounts/ejects the external drive
- The user clicks flash
The application state will contain an image path that is no longer
accessible, causing an ENOENT error when spawning the CLI process.
Change-Type: patch
Changelog-Entry: Display a user error if the image is no longer accessible when the writer starts.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit implements our own version of the `is-elevated` module. The
reason behind this is that `is-elevated` relies on lots of unnecessary
modules, that eventually require `spawn-sync` and `try-thread-sleep`,
which conditionally require dependencies that are not even declared in
their `package.json`, causing issues when concatenating the Etcher CLI.
See: https://github.com/resin-io/etcher/pull/1235
See: https://github.com/resin-io/etcher/pull/1228
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
`image-stream` returns image objects that look like this:
```js
{
stream: <readable stream>,
transform: <transform stream>,
size: {
original: <number>,
final: {
value: <number>,
estimation: <boolean>
}
},
...
}
```
While the GUI handles image objects that look like this:
```sh
{
path: <string>,
size: <number>,
...
}
```
It looks like we should share a common structure between both, so we can
use `image-stream` images in `drive-constraints`, for example.
Turns out that we actually transform `image-stream` image objects to GUI
image objects when the user selects an image using the image selector
dialog, which is another indicator that we should normalise this
situation.
As a solution, this commit does the following:
- Add `path` to `image-stream` image object
- Reuse `image-stream` image objects in the GUI, given they are a
superset of GUI image objects
See: https://github.com/resin-io/etcher/pull/1223#discussion_r108165110
Fixes: https://github.com/resin-io/etcher/issues/1232
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
`mountutils` is a native C++ NodeJS addon the Etcher team has been
working on to solve several issues we've been having with third party
unmount programs.
We'll see how this little module behaves after some real world usage.
I'm confident that it will fix the issues linked in this commit.
This commit also upgrades `npm` to 4.4.4 in Appveyor, given there is a
known building issue on Windows that is solved in a recent version.
Change-Type: minor
Changelog-Entry: Fix several unmount related issues in all platforms.
See: https://github.com/resin-io-modules/mountutils
Fixes: https://github.com/resin-io/etcher/issues/1177
Fixes: https://github.com/resin-io/etcher/issues/985
Fixes: https://github.com/resin-io/etcher/issues/750
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
The CLI still happily let you flash an image that doesn't fit on the
drive. This commit prevents such scenario right before flashing, but we
should still implement a smarter CLI drive detection widget for when the
user runs the CLI interactively.
Change-Type: patch
Changelog-Entry: Prevent flashing an image that is larger than the drive with the CLI.
Fixes: https://github.com/resin-io/etcher/issues/858
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
Currently, the Etcher CLI will print scary stack traces for every single
error (e.g: if you forgot to pass an image to the tool), given that
`errors.getDescription()` will return a stack trace if no other
description could be found.
This commit introduces an `ETCHER_CLI_DEBUG` environment variable, which
when set, it will cause the Etcher CLI to output stack traces, plus a
boolean `userFriendlyDescriptionsOnly` option to
`errors.getDescription()`, so we can control whether
`errors.getDescription()` returns things like stack traces, or
stringified error objects.
Change-Type: minor
Changelog-Entry: Don't print stack traces by default in the CLI.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
The current error handling logic is a mess. We have code that tries to
fetch information about errors in different places throughout the
application, and its incredibly hard to ensure certain types of error
get decent human friendly error messages.
This commit groups, improves, and tests all error related functions in
`lib/shared/errors.js`.
Here's a summary of the changes, in more detail:
- Move the `HUMAN_FRIENDLY` object to `shared/errors.js`
- Extend `HUMAN_FRIENDLY` with error descriptions
- Add `ENOMEM` to `shared/errors.js`
- Group CLI and `OSDialogService` mechanisms for getting an error title
and an error description
- Move error serialisation routines from `robot` to `shared/errors.js`
- Create and use `createError()` and `createUserError()` utility
functions
- Add user friendly descriptions to many errors
- Don't report user errors to TrackJS
Fixes: https://github.com/resin-io/etcher/issues/1098
Change-Type: minor
Changelog-Entry: Make errors more user friendly throughout the application.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This is one step towards enforcing the linter until we barely have to
check for style issues on code reviews.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
There are a lot of new rules since the last time I revised the ESLint
rules documentation.
I've updated the main `.eslintrc.yml` to include some newer additions,
plus I added another ESLint configuration file inside `tests`, so we can
add some stricted rules to the production code while relaxing them for
the test suite (due to the fact that Mocha is not very ES6 friendly and
Angular tests require a bit of dark magic to setup).
This is a summary of the most important changes:
- Disallow "magic numbers"
These should now be extracted to constants, which forces us to think of
a good name for them, and thus make the code more self-documenting (I
had to Google up the meaning of some existing magic numbers, so I guess
this will be great for readability purposes).
- Require consistent `return` statements
Some functions relied on JavaScript relaxed casting mechanism to work,
which now have explicit return values. This flag also helped me detect
some promises that were not being returned, and therefore risked not
being caught by the exception handlers in case of errors.
- Disallow redefining function arguments
Immutability makes functions easier to reason about.
- Enforce JavaScript string templates instead of string concatenation
We were heavily mixing boths across the codebase.
There are some extra rules that I tweaked, however most of codebase
changes in this commit are related to the rules mentioned above.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
- The type in `@type` should be surrounded by curly braces
- We should use `@type` in some cases where we used `@property`
- `@module` descriptions should go above such tag
- Namespaces should not declare their access type
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
We currently attempt to read extra metadata from ZIP files, such as a
logo, image name, image url, etc. In order to simplify the metadata
story, we decided that this metadata will not live on the image itself,
but rather on a centralised repo, which greatly simplified our custom
archive extraction logic and allows us to make use of these nice
features even when streaming the image directly from the internet.
We'll be working on bringing back this functionality from a centralised
repo in subsequent commits.
Change-Type: major
Changelog-Entry: Remove extended archives metadata extraction logic.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
The `image-stream` module currently returns a readable stream, a
transform stream, a "size", and an optional "estimatedUncompressedSize".
Based on this information, its hard to say what "size" represents. Some
format handlers return the compressed size and provide a decompression
transform stream while others return the decompressed stream directly
and put the decompressed size in "size".
As a way to simplify this, every format handler now returns a "size"
object with the following properties:
- `original`: The original compressed size
- `final.estimated`: Whether the final size is an estimation or not
- `final.value`: The final uncompressed size
As a bonus, we extract the file size retrieval logic to
`imageStream.getFromFilePath()`, which is the onlt part where the
concept of a file should be referred to.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This is a long lasting task. The `etcher-image-stream` project takes
care of converting any kind of image input into a NodeJS readable
stream, handling things like decompression in betwee, however its a
module that, except for weird cases, there is no benefit on having
separate from the main repository.
In order to validate the assumption above, we've left the module
separate for almost a year, and no use case has emerged to keep it
like that.
This commit joins the code and tests of that module in the main
repository.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
The path `lib/cli/cli.js` is confusing. Rename to `options.js` which is
how we were already referencing the file in `lib/cli/etcher.js`.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
There are certain application messages that should be re-used between
the CLI and the GUI. In order to allow such re-usability, we extract out
the application messages used in JavaScript into
`lib/shared/messages.js` as a collection of Lodash `_.template`
templates.
Notice this file doesn't include application messages included in
Angular templates directly since it'd be hard to refactor all of them.
We plan to move to React soon, which will allow moving the remaining
messages very easily.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
- Inline dictionary of common error codes and friendly descriptions
We used to rely on `resin-cli-errors` for this, however the friendly
descriptions set there can be usually very Resin CLI specific, and thus
confusing to Etcher users.
The dictionary, along with other error related utilities live in
`lib/cli/errors.js`.
- Print error descriptions and codes if they are found
- Move `utils.printError()` to `errors.print()`
Change-Type: minor
Changelog-Entry: Improve Etcher CLI error messages.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>