Hyper-V server is the free virtualization OS from Microsoft to compete head to head with the free ESXi OS. When running in large farms or domain joined, Hyper-V seems to work pretty decently. But when you just want a single host that you manage with Windows 10, or let alone MacOS, Hyper-V can become a nightmare. Be careful that Hyper-V Management Tools and Hyper-V Platform are selected. After Hyper-V is enabled, you will be prompted to restart your Windows 10 PC to finish installing the.
Hyper-V server is the free virtualization OS from Microsoftto compete head to head with the free ESXi OS. When running in large farms ordomain joined, Hyper-V seems to work pretty decently. But when you just want asingle host that you manage with Windows 10, or let alone MacOS, Hyper-V canbecome a nightmare.
So why would you go the Hyper-V route and not the ESXi routein that case? Well. ESXi has a very specific taste for hardware. Only certainraid controllers, certain NIC’s etc are supported. While Hyper-V based on theWindows 2016/2019 OS usually gives you more freedom to play around with, and itsupports RAID straight from the software. So essentially, you can run it onalmost any white box,.
In this post I’ll be installing Hyper-V server on my DellT710 as a single-stand-alone machine, while configuring it solely from a MacOSbased laptop.
First things first, download Hyper-V 2016. You could opt for the 2019 version, but there are some quirks on that one with regards to RDP, which we will need when we are configuring it. (so much for the good start). Avira or avast for mac. I installed the 2016 version on Disk 0, an SSD that is attached to a standard SAS/SATA controller. After the installation, set the password for the administrator account on the console.
And after logging in, enable RDP by typing 7 <enter>,E <enter>, 1 <enter> <enter> on the pop-up.
Next we need to know the IP of the server so we can connectto it: Type: 8 <enter> and note the IP listed:
Then on your Mac, download the latest Microsoft RemoteDesktop application and create a connection to the server.
On the application, select the + and then select Desktop. On the PC Name field enter the IP address and click save. Your connection will be saved under Saved Desktops. Double click and login with administrator/<password set>. On the pop-up regarding a certificate validation, click continue.
You will now have the remote desktop loaded on your Mac.First things first, lets get the updates by issuing 5 <enter>, D(download only) <enter> . Then 6 (download updates), A (all updates) andhave the system update itself.
In my server I have a custom NIC for which the drivers arenot loaded by default. I’ve been working on the on-board QLogic NIC for now,but I wanted to enable my 2x 10Gb SFP (HP HC523SFP) NIC as well. So, in caseyour NIC did not load either, through the console (as RDP would not work if youdon’t have any connection), follow the next steps.
In my case, the NIC driver is actually an executable thatextracts itself and starts the installer, but in my system, the drivers are for2012R2, not 2016 and thus the auto installer doesn’t work. We have to go theold-school route of installing the drivers.
First, the extraction. The extract only of the softwaredoesn’t work and as I promised I’d only use MacOS we can’t extract them onthere either. So, we run the installer, but leave the error message in thebackground while we grab the extracted files:
The temporary files location can actually be found in thelog file under c:cpqsystemlog
Once we grabbed all the required files, we can now dopnputil.
And let’s see if we have additional NIC’s by doing an ipconfig/all (or even better, issue PowerShell and then type Get-NetAdapter)
In order to create and manage VM’s we could opt for a full PowerShellbased management. But given we’d have to RDP constantly into the server (from MacOS),it’s probably easier to install the Windows Admin Center.
For this, download the admin center toolkit: https://www.microsoft.com/en-us/cloud-platform/windows-admin-centerput it on a USB drive to copy it to the server (or open a share or any othermeans of copying it to the server) and from a command prompt in the server run:
This will install the Admin Center on port 443 on the serverquietly. Wait for a few moments and then using the browser on the Mac go to https://server and login using the servercredentials.
Once the admin center is loaded, you can go to the Hyper-V section and create / manage VM’s. On the file-services tab you can also upload/download files straight into/from the server
The next part is getting the disks into a storage pool. Thisis required when you have multiple disks and no hardware raid controller (oryou want to have the freedom to change the disk pool quickly). You can do thisvia the admin center (Storage) or through PowerShell as I do in this example:
In order to get all our disks into the pool, we create an array of all the disks that are available for the pool:
Then we create the storage pool:
Once we have the pool, we create a new volume on that andset the volume to a stripe level. You can select Simple (no redundancy, max performance), Mirror, and Parity (raid5 or 6).
In my case, I’m just setting up a mirror, using maximum size
And that created and formatted our V: drive for storage ofVM’s. Let’s create a VM folder and Virtual HardDisk Folder and set the defaultsto those folders:
So now that the storage is done, let’s create the VirtualSwitch. Again, you can do this via the Admin Center, but through PowerShell it’sjust as easy…
In my case I want to enable the switch with my 2x 10Gb NIC’s, using Get-Netadapter I’ able to retrieve my Ethernet friendly names and I can create the switch using the following command:
If you have dedicated NIC’s for just the VM’s you can set the AllowManagementOS to $false
Given we set the challenge to only work on a Mac, you willnotice that connecting to VM’s is not directly possible. Even with the officialMicrosoft Remote Desktop software available for OSX. But fear not, anothercompany has released an application that does work. It is called RoyalTSX andits available for Windows and Mac. While the suite itself can do much more, weonly need the free version of the software.
There are 2 ways to connecting to a VM. The Console (the usually screen+keyboard of a machine) or remote access (either RDP, PowerShell,etc for Windows, or SSH for Linux). In this case, we want to get to the console. And RDP for Hyper-V allows us to do so by connecting to the host with an InstanceID. In order to get the instance ID, go to your VM in the Admin Center console and select More to download the RDP file:
If you open the RDP file, you will notice a GUID if you open the downloaded file with a text editor. You can also find the GUID quickly on the Summary view of the Virtual Machines (which lists changed/started/created VM’s). Copy the GUID and open Royal TSX. Under Remote Desktop create a new entry with the name of the VM. For the Remote Desktop entries, put the name/ip of the server and port 3389.
Then scroll down to Hyper-V and put in Hyper-V host, connect to a specific instance. Put in the port 2179 and put in the InstanceID:
Then apply and close and connect.
And done!
64-bit |
macOS (.app) |
Windows (.exe) |
Debian (.deb) |
Fedora (.rpm) |
Other Linux distros (.AppImage) |
The goal of the project is to create a beautiful and extensible experience for command-line interface users, built on open web standards. In the beginning, our focus will be primarily around speed, stability and the development of the correct API for extension authors.
In the future, we anticipate the community will come up with innovative additions to enhance what could be the simplest, most powerful and well-tested interface for productivity.
Extensions are available on npm. We encourage everyone to includehyper
in the keywords
field in package.json
. Safari browser download for mac.
Then edit .hyper.js
and add it to plugins
Hyper
will show a notification when your modules are installed to .hyper_plugins
.
All command keys can be changed. In order to change them, edit.hyper.js
and add your desired change to keymaps
.
Then Hyper will change the default with your custom change.
Example: 'window:devtools': 'Cmd+Alt+O'
macOS | ~/Library/Application Support/Hyper/.hyper.js |
Windows | $Env:AppData/Hyper/.hyper.js |
Linux | ~/.config/Hyper/.hyper.js |
Note: config at ~/.hyper.js
still supported, but will be ignored, if config in application directory present. Otherwise it will be moved to the application directory at first run.
The config
object seen above in.hyper.js
admits the following Now tv download mac.
Property | Default | Description |
updateChannel | 'stable' | The update channel to receive updates from |
fontSize | 12 | The default size in pixels for the terminal |
fontFamily | 'Menlo, DejaVu Sans Mono, Lucida Console, monospace' | The font family to use with optional fallbacks |
uiFontFamily | '-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, ..' | The font family to use for the UI with optional fallbacks |
fontWeight | 'normal' | The default font weight: 'normal' or 'bold' |
fontWeightBold | 'bold' | The font weight for bold characters: 'normal' or 'bold' |
cursorColor | 'rgba(248,28,229,0.8)' | The color of the caret in the terminal |
cursorAccentColor | '#000' | The text color under BLOCK cursor |
cursorShape | 'BLOCK' | The shape of the caret in the terminal. Available options are: 'BEAM', 'UNDERLINE', 'BLOCK' |
cursorBlink | 'false' | If true, cursor will blink |
foregroundColor | '#fff' | The color of the main text of the terminal |
backgroundColor | '#000' | The color and opacity of the window and main terminal background |
selectionColor | 'rgba(248,28,229,0.3)' | The background color/opacity of the text selection in terminal |
borderColor | '#333' | The color of the main window border and tab bar |
css | ' | Custom CSS to include in the main window |
padding | '12px 14px' | CSS padding values for the space around each term |
colors | { black: '#000000', red: '#ff0000', .. } | A list of overrides for the color palette. The names of the keys represent the 'ANSI 16', which can all be seenin the default config. |
shell | ' | A path to a custom shell to run when Hyper starts a new session |
shellArgs | '['--login']' | An array of shell arguments |
env | {} | An object of environment variables to set before launching shell |
windowSize | [540, 380] | The default width/height in pixels of a new window |
scrollback | 1000 | The number of rows to be persisted in terminal buffer for scrolling |
copyOnSelect | false | If true, selected text will automatically be copied to the clipboard |
quickEdit | false | If true, on right click selected text will be copied or pasted if no selection is present (true by default on Windows) |
defaultSSHApp | true | If true, Hyper will be set as the default protocol client for SSH |
modifierKeys | {altIsMeta: false} | Change the behaviour of modifier keys to act as meta key |
showHamburgerMenu | true on Linux/Windows, false on macOS | Change the visibility of the hamburger menu. Available options are: true, false |
showWindowControls | ' | Change the position/visibility of the window controls. Available options are: true, false, 'left' |
Extensions are universal Node.js modules loaded by both Electron and the renderer process.
The extension system is designed around composition of the APIs we use to build the terminal: React
components andRedux
actions.
Instead of exposing a custom API method or parameter for every possible customization point, we allow you to intercept and compose every bit of functionality!
The only knowledge that is therefore required to successfully extendHyper
is that of its underlying open source libraries.
You can find additional details about plugin developmentin the Hyper repository.
Your module has to expose at least one of these methods:
Method | Invoked from | Description | ||||||
onApp | Electron | Invoked when the app first loads. If a plugin reloads, it's invoked again with the existing app. Parameters:
| ||||||
onWindow | Electron | Invoked when each window is created. If a plugin reloads, it's invoked again with the existing windows. Parameters:
| ||||||
onUnload | Electron | Invoked when a plugin is removed by the user. Parameters:
| ||||||
decorateConfig | Electron / Renderer | v0.5.0+. Allows you to decorate the user's configuration. Parameters:
| ||||||
decorateEnv | Electron | v0.7.0+. Allows you to decorate the user's environment by returning a modified environment object. Parameters:
| ||||||
decorateMenu | Electron | Invoked with the Electron's Parameters:
| ||||||
decorateBrowserOptions | Electron | Allows you to decorate Electron's Parameters:
| ||||||
onRendererWindow | Renderer | Invoked when a plugin is first loaded or subsequently reloaded in each window. Parameters:
| ||||||
middleware | Renderer | A custom Redux middleware that can intercept any action. Subsequently we invoke the | ||||||
reduceUI reduceSessions reduceTermGroups | Renderer | A custom reducer for the
| ||||||
getTabsProps | Renderer | Passes down props from
| ||||||
getTabProps | Renderer | Passes down props from
| ||||||
getTermGroupProps | Renderer | Passes down props from
| ||||||
getTermProps | Renderer | Passes down props from
| ||||||
mapHyperState mapTermsState mapHeaderState mapNotificationsState | Renderer | A custom mapper for the state properties thatcontainer componentsreceive. Note that for children components to get these properties, you have to pass them down using the corresponding methods (like Must return an extended object of the map passed.
| ||||||
mapHyperDispatch mapTermsDispatch mapHeaderDispatch mapNotificationsDispatch | Renderer | A custom mapper for the dispatch properties. Must return an extended object of the map passed.
| ||||||
decorateHyper decorateNotifications decorateNotification decorateHeader decorateTabs decorateTab decorateTerms decorateTermGroup decorateSplitPane decorateTerm | Renderer | Invoked with the Parameters:
|
The user can hot-load and hot-reload plugins by pressing Command + R (refresh). Please strive to make plugins that don't require a complete restart of the application to work.
Plugins affecting the `BrowserWindow` will the effect on new windows after hot-reload.
In the future we might do this automatically.
When developing, you can add your plugin to.hyper_plugins/local
and then specify it under the localPlugins
array in.hyper.js
. We load new plugins:
plugins
or localPlugins
)The process of reloading involves
npm prune
and npm install
in.hyper_plugins
.require.cache
in both electron and the renderer processon*
methods on the existing instances and re-rendering components with the fresh decorations in place.macOS | ~/Library/Application Support/Hyper/.hyper_plugins |
Windows | $Env:AppData/Hyper/.hyper_plugins |
Linux | ~/.config/Hyper/.hyper_plugins |
Note: plugins at ~/.hyper_plugins
still supported, but will be ignored, if plugins in application directory present. Otherwise they will be moved to the application directory at first run.
Note: on the main process, plugins are registered as soon as possible (we fire onLoad
). On the browser, it's up to the user to trigger their load by pressing command+R. We put the user in control of the loading in this way to prevent them from losing critical work by extensions that reset state or don't preserve it correctly.
We give you the ability to provide a higher order component for every piece of the Hyper
UI.
Its structure is as follows:
All the decorate*
methods receive the following references in an object passed as the second parameter:
React | The entire React namespace. |
notify | A helper function that shows a desktop notification. The first parameter is the title, the second is the optional body of the notification, and the third is another optional parameter which can be used to log details to the development console. To pass these details, simply provide and object with an |
Notification | The Notification component in case you want to re-use it. |
All the components accept the following two properties to extend their markup:
customChildren | An array of Element or a singleElement to insert at the bottom of the component. |
customChildrenBefore | The same as the above property, but inserted as the first child element(s) of the component. |
Your higher order component can supply a onDecorated
property to the decorated component to get a reference to its instance.
Your Term higher order component can supply anonCursorMove
handler property that be called when cursor has moved with an object parameter representing its relative position to Term origin:
x | Horizontal position in pixels |
y | Vertical position in pixels |
width | Cursor width in pixels |
height | Cursor height in pixels |
col | Horizontal position in columns |
row | Vertical position in rows |
We encourage you to maintain compatibility with other decorators. Since many can be set, don't assume that yours is the only one.
For example, if you're passing children, compose potential existing values:
Or if you use onDecorated
property
All theRedux actionsare available for you to handle through your middleware and reducers. For an example, refer to the Hyperpowerreference plugin.
Side effects occur in two fundamental forms:
In all cases, the side effect is passed as the effect
key in the action and later handled by our middleware.
This means that you can override, compose or completely eliminate effects! In other words, this is how you can change the default functionality or behavior of the app.
As an example, consider the action we use to increase the font size when you press Command+=
:
Hyper
achieves a lot of its speed and functionality thanks to the power ofxterm.js
The Electron app
objects are extended with the following properties:
config | An Object with the config block from.hyper.js . |
plugins | An Object with helpers for plugins. |
getWindows | A Function that returns an Set of all the open windows. |
createWindow | A Function that will create a new window. Accepts an optional callback that will be passed as the new window's init callback. |
Electron BrowserWindow
objects are extended with the following parameters:
rpc | An EventEmitter that allows for communication with the window process. |
sessions | A Map of Session objects which hold the communication with each term's pty. |
Renderer windows are similarly extended with:
rpc | An EventEmitter that allows for communication with the window process. |
store | The Redux Store object. This allows access todispatch actions or read the global state withgetState . |
The rpc
object is symmetrical between browser and renderer process. The API is the same as Node.js, with the exception that it only admits a single object as its parameters only:
The following extension simply alters the config to add CSS and yellow colors! Here's thecode.
Themes are simply plugins! Only one hook, decorateConfig
is needed:
I grabbed the class names by inspecting the term with Devtools, which you can trigger from View -> Toggle Developer Tools
. When you do so, notice that some classes are automatically generated and followed by a random nonce (e.g.: term_13hv8io
). Ignore those: they change with every new window!
Notice the emphasis on playing nice with other extensions. Specifically, we create a new object, extend only the keys we are interested in, and we compose the CSS to preserve the user's setting and that of other authors':
The following extension renders particles as the caret moves:
Let's walk throughits code.
First, we intercept the Redux action SESSION_ADD_DATA
. You can find the full list of actionsin the repository.
Notice that we don't re-dispatch the action, which means we never render the output of the command to the terminal. Instead, we dispatch an action of our own, which we grab in the uiReducer
and later map:
We then want to decorate the <Term>
component so that we can access the underlying caret.
However, <Term>
is not a container that we can map props to. So we use getTermProps
to pass the property further down:
The extension thenreturnsa higher order component to wrap <Term>
. Notice we pass the onDecorated
property to access the base Term component and its DOM ref, and theonCursorMove
property to use Hyper cursor API: