1 month Ago

How Encodo sets up new workstations

Published by marco on in Tips & Tricks

     At Encodo, we’ve recently set up a few new workstations with Windows 8.1 and wanted to share the process we use, in case it might come in handy for others.

Windows can take a long time to install, as can Microsoft Office and, most especially, Visual Studio with all of its service packs. If we installed everything manually every time we needed a new machine, we’d lose a day each time.

To solve this problem, we decided to define the Encodo Windows Base Image, which includes all of the standard software that everyone should have installed. Using this image saves a lot of time when you need to either install a new workstation or you’d like to start with a fresh installation if your current one has gotten a bit crufty.

Encodo doesn’t have a lot of workstations, so we don’t really need anything too enterprise-y, but we do want something that works reliably and quickly.

After a lot of trial and error, we’ve come up with the following scheme.

  • Maintain a Windows 8.1 image in a VMDK file
  • Use VirtualBox to run the image
  • Use Chocolatey for (almost) all software installation
  • Use Ubuntu Live on a USB stick (from which to boot)
  • Use Clonezilla to copy the image to the target drive

Installed Software

The standard loadout for developers comprises the following applications.

These are updated by Windows Update.

  • Windows 8.1 Enterprise
  • Excel
  • Powerpoint
  • Word
  • Visio
  • German Office Proofing Tools
  • Visual Studio 2013

These applications must be updated manually.

  • ReSharper Ultimate
  • Timesnapper

The rest of the software is maintained with Chocolatey.

  • beyondcompare (file differ)
  • conemu (PowerShell enhancement)
  • fiddler4 (HTTP traffic analyzer)
  • firefox
  • flashplayerplugin
  • git (source control)
  • googlechrome
  • greenshot (screenshot tool)
  • jitsi (VOIP/SIP)
  • jre8 (Java)
  • keepass (Password manager)
  • nodejs
  • pidgin (XMPP chat)
  • poshgit (Powershell/Git integration)
  • putty (SSH)
  • smartgit (GIT GUI)
  • stylecop (VS/R# extension)
  • sublimetext3 (text editor)
  • sumatrapdf (PDF viewer)
  • truecrypt (Drive encryption)
  • vlc (video/audio player/converter)
  • winscp (SSH file-copy tool)
  • wireshark (TCP traffic analyzer)

Maintaining the Image

This part has gotten quite simple.

  1. Load the VM with the Windows 8.1 image
  2. Apply Windows Updates
  3. Update ReSharper, if necessary
  4. Run choco upgrade all to update all Chocolatey packages
  5. Shut down the VM cleanly

Writing the image to a new SSD

The instructions we maintain internally are more detailed, but the general gist is to do the following,

  1. Install the SSD in the target machine
  2. Plug in the Ubuntu Live USB stick
  3. Plug in the USB drive that has the Windows image and Clonezilla on it
  4. Boot to the Ubuntu desktop
  5. Make sure you have network access
  6. Install VirtualBox in Ubuntu from the App Center
  7. Create a VMDK file for the target SSD
  8. Start VirtualBox and create a new VM with the Windows image and SSD VMDK as drives and Clonezilla configured as a CD
  9. Start the VM and boot to Clonezilla
  10. Follow instructions, choose options and then wait 40 minutes to clone data
  11. Power off Clonezilla
  12. Shut down Ubuntu Live
  13. Unplug the USB drive and stick
  14. Boot your newly minted Windows 8.1 from the SSD
  15. Install Lenovo System Update (if necessary) and update drivers (if necessary)
  16. Add the machine to the Windows domain
  17. Remote-install Windows/Office licenses and activate Windows
  18. Remote-install Avira antivirus
  19. Grant administrator rights to the owner of the laptop
  20. Use sysprep /generalize to reset Windows to an OOB (Out-of-box) experience for the new owner

Conclusion

We’re pretty happy with this approach and the loadout but welcome any feedback or suggestions to improve them. We’ve set up two notebooks in the last three weeks, but that’s definitely a high-water mark for us. We expect to use this process one more time this year (in August, when a new hire arrives), but it’s nice to know that we now have a predictable process.

v2.0-beta2: Code generation, IOC and configuration

Published by marco on in Programming

The summary below describes major new features, items of note and breaking changes. The full list of issues is also available for those with access to the Encodo issue tracker.

Highlights

In beta1, we read about changes to configuration, the data driver architecture, DDL commands, and security and access control in web applications.

In beta-2, we made the following additional improvements:

Goodbye, old friends

This release addressed some issues that have been bugging us for a while (almost 3 years in one case).

  • QNO-3765 (32 months): After a schema migration caused by a DatabaseException on login, restart the application
  • QNO-4117 (27 months): PreferredType registration for models is not always executed
  • QNO-4408 (18 months): When access to the remoting server is unauthorized, the web site should respond with an error
  • QNO-4506 (14 months): The code generator should generate the persistent object and metadata references in separate classes
  • QNO-4507 (14 months): Business objects for modules should not rely on GlobalContext in generated code

You will not be missed.

Breaking changes

As we’ve mentioned before, this release is absolutely merciless in regard to backwards compatibility. Old code is not retained as obsolete Obsolete. Instead, a project upgrading to 2.0 will encounter compile errors.

That said, if you arm yourself with a bit of time, ReSharper and the release notes (and possibly keep an Encodo employee on speed-dial), the upgrade is not difficult. It consists mainly of letting ReSharper update namespace references for you. In cases where the update is not so straightforward, we’ve provided release notes.

V1 generated code support

One of the few things you’ll be able to keep (at least for a minor version or two) is the old-style generated code. We made this concession because, while even a large solution can be upgraded from 1.13.0 to 2.0 relatively painlessly in about an hour (we’ve converted our own internal projects to test), changing the generated-code format is potentially a much larger change. Again, an upgrade to the generated-code format isn’t complicated but it might require more than an hour or two’s worth of elbow grease to complete.

Therefore, you’ll be able to not only retain your old generated code, but the code generator will continue support the old-style code-generation format for further development. Expect the grace period to be relatively short, though.

Regardless of whether you elect to keep the old-style generated code, you’ll have to do a little bit of extra work just to be able to generate code again.

  1. Manually update a couple of generated files, as shown below.
  2. Compile the solution
  3. Generate code with the Quino tools

Before you can regenerate, you’ll have to manually update your previously generated code in the main model file, as shown below.

Previous version

static MyModel()
{
  Messages = new InMemoryRecorder();
  Loader = new ModelLoader(() => Instance, () => Messages, new MyModelGenerator());
}

public static IMetaModel CreateModel(IExtendedRecorder recorder)
{
  if (recorder == null) { throw new ArgumentNullException("recorder"); }

  var result = Loader.Generator.CreateModel(recorder);

  result.Configure();

  return result;
}

// More code …

/// <inheritdoc/>
protected override void DoConfigure()
{
  base.DoConfigure();

  ConfigurePreferredTypes();
  ApplyCustomConfiguration();
}

Manually updated version

static MyModel()
{
  Messages = new InMemoryRecorder();
  Loader = new ModelLoader(() => Instance, () => Messages, new MyModelGenerator());
}

public static IMetaModel CreateModel(IExtendedRecorder recorder)
{
  if (recorder == null) { throw new ArgumentNullException("recorder"); }

  var result = Loader.Generator(MyModel)new MyModelGenerator().CreateModel(
    ServiceLocator.Current.GetInstance<IExpressionParser>(),
    ServiceLocator.Current.GetInstance<IMetaExpressionFactory>(),
    recorder
  );

  result.ConfigurePreferredTypes();
  result.ApplyCustomConfiguration();

  return result;
}

/// <inheritdoc/>
protected override void DoConfigure()
{
  base.DoConfigure();

  ConfigurePreferredTypes();
  ApplyCustomConfiguration();
}

Integrate into the model builder

In the application configuration for the first time you generate code with Quino 2.0, you should use:

ModelLoader = MyModel.Loader;
this.UseMetaSimpleInjector();
this.UseModelLoader(MyModel.CreateModel);

After regenerating code, you should use the following for version-2 generated code:

ModelLoader = MyModel.Loader;
this.UseMetaSimpleInjector();
this.UseModelLoader(MyModelExtensions.CreateModelAndMetadata);

…and the following for version-1 generated code:

ModelLoader = MyModel.Loader;
this.UseMetaSimpleInjector();
this.UseModelLoader(MyModel.CreateModel);

Still to do by RTM

As you can see, we’ve already done quite a bit of work in beta1 and beta2. We have a few more tasks planned for the feature-complete release candidate for 2.0

  • Move the schema-migration metadata table to a module.

    The Quino schema-migration extracts most of the information it needs from database schema itself. It also stores extra metadata in a special table. This table has been with Quino since before modules were supported (over seven years) and hence was built in a completely custom manner. Moving this support to a Quino metadata module will remove unnecessary implementation and make the migration process more straightforward. (QNO-4888)
     

  • Separate collection algorithm from storage/display method in IRecorder and descendants.

    The recording/logging library has a very good interface but the implementation for the standard recorders has become too complex as we added support for multi-threading, custom disposal and so on. We want to clean this up to make it easier to extend the library with custom loggers. (QNO-4888)
     

  • Split up Encodo and Quino assemblies based on functionality.

    There are only a very dependencies left to untangle (QNO-4678, QNO-4672, QNO-4670); after that, we’ll split up the two main Encodo and Quino assemblies along functional lines. (QNO-4376)
     

  • Finish integrating building and publishing NuGet and symbol packages into Quino’s release process.

    And, finally, once we have the assemblies split up to our liking, we’ll finalize the Nuget packages for the Quino library and leave the direct-assembly-reference days behind us, ready for Visual Studio 2015.
    (QNO-4376)
     

That’s all we’ve got for now. See you next month for the next (and, hopefully, final update)!

We are watching and we are Legion

Published by marco on in Quotes

“The threat is no longer Big Brother, but instead thousands of Little Brothers.”

The main advantage of a type-safe language

Published by marco on in Quotes

“A type system is the most cost-effective unit test you’ll ever have.”
Peter Hallam

2 months Ago

On the inadequacy of language

Published by marco on in Quotes

“He knows that there are in the soul tints more bewildering, more numberless, and more nameless than the colours of an autumn forest… Yet he seriously believes that these things can every one of them, in all their tones and semitones, in all their blends and unions, be accurately represented by an arbitrary system of grunts and squeals. He believes that an ordinary civilized stockbroker can really produce out of his own inside noises which denote all the mysteries of memory and all the agonies of desire.”
Words by G.K. Chesterton (The Language Log)

The first comment in the post includes a similar quote from Flaubert:

“Language is a cracked kettle on which we beat out tunes for bears to dance to, while all the time we long to move the stars to pity.”