We try our best to check that the images the user select are too big for
the selected drive as early as possible, but this probes to be
problematic with certain compressed formats, like bzip2, which doesn't
store any information about the uncompressed size, requiring a ~50s
intensive computation as a minimum to find it out.
For these kinds of formats, we don't perform an early check, but instead
gracefully handle the case where the drive doesn't have any more space.
This PR handles an `ENOSPC` error by displaying the alert orange ribbon,
and prompting the user to retry with a larger drive. This is a huge
improvement over the cryptic `EIO` error what was thrown before, and
over having Etcher freeze at a certain percentage point.
Change-Type: minor
Changelog-Entry: Display a nice alert ribbon if drive runs out of space.
See: https://github.com/resin-io/etcher/issues/571
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This setting makes Etcher not filter non-removable drives, allowing you to
arbitrarily write to your system drives.
This is a dangerous option, therefore we present it in a separate section of
the settings page, and show an informative confirmation dialog.
Change-Type: minor
Changelog-Entry: Add an "unsafe" option to bypass drive protection.
Fixes: https://github.com/resin-io/etcher/issues/480
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, if we cancel elevation, we'd get a big scary validation error
about `passedValidation` not being passed to the flash results object.
This fix also requires some adjustments to `wasLastFlashSuccessful()` in
order to adapt to the cancellation scenario.
Since a cancelled elevation request means the writing never took place,
`wasLastFlashSuccessful()` returns `true` if so, without even looking at
`passedValidation`.
Change-Type: patch
Changelog-Entry: Fix error when cancelling an elevation request.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
There is a small flaw in the current state validation rules where a
speed that equals zero will be considered as if the speed was missing
giving that `!0 == true`.
Changelog-Entry: Fix state validation error when speed equals zero.
Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
JSCS has merged with ESLint. This is the perfect excuse to move to
ESLint and unify both JSHint and JSCS hints under ESLint.
This PR also deprecates `gulp lint` in favour of `npm run lint`.
See: https://medium.com/@markelog/jscs-end-of-the-line-bc9bf0b3fdb2#.zbuwvxa5y
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* refactor: getter/setter interface for SettingsModel
This PR introduces a getter/setter interface for `SettingsModel`, which
replaces the old way of managing setting values by simply assigning
properties to an object.
This is the first step towards moving the settings functionality to the
Redux store.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* refactor: store settings in redux store
The state data structure now contains a property called `settings`,
which is a map containing all setting values.
The list of supported settings can be calculated by retrieving the keys
from the `settings` object, which means that if we support a setting, we
must include a default.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* feat: store settings in localStorage
This functionality was deleted by acb0de2 when moving the settings
object to the redux store, promising that the feature will be added back
in a future commit.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This is a rather big PR that moves the flash results information to the
Redux store, which simplifies and improves a lot of things as throughly
described in the commits that introduced Redux.
Here's a summary of the changes:
- Add a `flashResults` property to the store.
- Validate the contents of `flashResults`, handling certain edge cases
that make the modal incoherent.
- Split `ImageWriterService.setFlashing()` to
`ImageWriterService.setFlashingFlag()` and
`ImageWriterService.unsetFlashingFlag()`.
- Require the flash results to be passed to
`ImageWriterService.unsetFlashingFlag()`.
- Stop resolving the flash results from `ImageWriterService.flash()`.
- Implement `ImageWriterService.getFlashResults()`.
- Make the `RESET_FLASH_STATE` action reset the flash results.
- Access the source checksum from the store in the "finish" page,
instead of requiring the controller to pass it as a state parameter.
- Implement `.wasLastFlashSuccessful()` function in the main controller
to replace the `.success` property.
- Completely remove the `.success` property in the main controller.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
So the property is consistent from what we get from `etcher-image-write`
and we don't have to unnecessarily rename ourselves to pass it to the
model.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
- From `Etcher.analytics` to `Etcher.Modules.Analytics`.
- From `Etcher.image-writer` to `Etcher.Modules.ImageWriter`.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
We have logic that displays useful log messages about the state of the
flashing, as well as update the window progress in each oeprating system
(dock in OS X, task bar in Windows, etc), however since this logic lives
in the controller, the progress reports are completely frozen if the
user navigates away from the main screen (to the settings page for
example).
As a solution, we move the code that subscribes to the state change
events to a global `.run()` so it can persist page changes.
Since making sure the listeners are unregistered is not relevant anymore
(since the code is not running in a controller anymore), we get rid of
`NotifierService`, a module we built for this purpose, and directly
subscribe to the Redux store instead.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
ES6 fat arrows provide reasonable `this` behaviour, which protects us
from some subtle accidental bugs, and erradicates `const self = this`
from the codebase.
Far arrows were not applied in Mocha code and AngularJS
controllers/services constructors since these frameworks rely on
`.bind()` on those functions.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, the "flash" property of the application state containing both
the actual flashing state, and the flashing flag.
To simplify things, the following changes have been introduced:
- Move `flash.flashing` to `isFlashing`.
- Move `flash.state` to `flashState`.
- Rename `SET_FLASHING` to `SET_FLASHING_FLAG`.
- Extract `UNSET_FLASHING_FLAG` from `SET_FLASHING_FLAG`.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Referencing actions as properties of an object is more reliable than
just hardcoding strings everywhere.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, we were taking care of resetting the flashing state manually
across several controllers. Now that data mutations live in a single
place, we trigger a flash state reset whenever the flashing flag is set
to false, which reliably handles every case and allows us to forget
about it.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, Etcher's application state is stored among various models,
making it a bit hard to mentually visualise the application state at a
certain point of execution. This also means that some quirky bugs
appear, and we have to take non-elegant measures to mitigate them, for
example:
- The current drive selection might be invalid if the current available
drive list doesn't contain it anymore.
- The progress state might be modified while there is no flashing in
process.
- We have to rely on event emission to propagate the current state to
the application progress bar.
- The validity of a selected drive might depend on the currently
selected image.
While all these issues can be addressed with common programming
techniques, Redux introduces a new way of thinking about the application
state that make the above problems non-existent, or trivial to fix.
This PR creates a Redux store containing the logic used to mutate state
from:
- `SelectionStateModel`.
- `DrivesMode`.
- `ImageWriterService`.
We are also making extra effort to preserve the public APIs from the
models, which we will be simplifying in later commits.
There is still much to be done, but we're happy to be taking the first
steo towards a much cleaner architecture.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
The concept of a drive scanner lends itself very well to the concept of
"reactive programming", since the "available drives" make perfect sense
as an "Observable".
For this reason, the module was re-implemented using RxJS, which greatly
simplifies things and erradicates certain edge cases we were protecting
ourselves from automatically.
Other changes made in this PR:
- `DriveScannerService` no longer requires `DrivesModel`. The
`DriveScannerService` is the one in charge of populating the model.
- `DriveScannerService.scan()` no longer returns an `EventEmitter`. The
service itself is now an `EventEmitter`.
- `DriveScannerService` now emits a `drives`, not a `scan` event.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, `DriveScannerService` is in charge of both scanning the
available drives and maintaining the state of the currently detected
drives.
To honour the single responsibility principle, we split this service
into a `DrivesModel`, which is incharge of maintaining the state without
caring how they are detected, and `DriveScannerService`, which only
scans the available drives and modified `DrivesModel` accordingly.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Show speed during check
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Display ETA during flash and check
Fixes: https://github.com/resin-io/etcher/issues/256
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
After this change, the CLI becomes the only entity actually performing
I/O with the devices, and the GUI is just a wrapper around it.
When you click "Flash", the GUI spawns the CLI with all the appropriate
options, including `--ipc`, which uses an IPC communication channel to
report status back to the parent process.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This file runs the Etcher CLI if the binary was ran with
`ELECTRON_RUN_AS_NODE`, or the GUI otherwise.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This refactoring will be useful on future changes, where there will be
a single application entry point that will execute the CLI or the GUI
version depending on the environment.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>