Search This Blog

September 16, 2020

Setting Default User For Imported WSL Distro

I have a dual hard-drive laptop with the primary being an SSD for quick-boot and the secondary being an HDD. The primary one, unfortunate for today's demand is a little too less in space of just 250 GB but the secondary one is good with 1 TB in space. 

 As a discipline, as much as possible I host most of my files and software installations in my largish secondary drive. As with WSL, when you install it from Microsoft Store (earlier known as Windows Store), it defaults to windows operating system location, which becomes my space constrained primary drive. 

To preserve the space in my primary drive, I wanted to change the storage location of my WSL distro to my secondary drive. This is possible with WSL import/export commands. See WSL Cheatsheet for reference. 

After you import a WSL distribution, you may need to tell WSL 2 to start the distribution using the Linux user account you created when you first created the distribution. Unfortunately, this is not taken care of by default from the export/import procedure; see WSL/Issue in Github, if you are curious. 

The Microsoft Docs however proposes a way to change the default user for a distro, which didn't work for me for some reason. This is what you should try first, which is about executing something like `ubuntu config --default-user my_default_username` depending upon the name of your distro executable. 

Microsoft Docs also proposes a distro specific configuration that you can make with `wsl.conf`. This is a per distro launch configuration setting. Using this you can automatically configure certain functionality in WSL that will be applied every time you launch the subsystem using `wsl.conf`. This file is located in `/etc/wsl.conf` of your target distro, where the contents looks like below:

-- --

Now if even this fails, know the DefaultUid of this user who you wanted to make a default one and use that in setting it up manually in the windows registry like below screenshot:


In the screen-shot above, I had exported my Ubuntu-20.04 distro where I had created a default username kartz at the time of its installation from Microsoft Store. Ubuntu-20 is the new distro that was created by importing from the exported image tar file and I wanted to have kartz as the default username in this distro, because I have my working environment all set to this user in this distro created from imported image. Apparently in my case the value turned out to be 1000.

For easy copy-edit-pasting, I share the snippet below as gist:

---- 

Hope that get you going easy with WSL 2!!..

September 6, 2020

WSL For Development In Windows 10 Is The New Kool-Aid

I had been a happy-go Java developer on Windows platform. And then I had to ride the Ruby-on-Rails wave over Linux platform, only to realize how much I didn't know about productivity with automation. Later I moved onto MacOS to experience bliss before starting to hate it for one thing after the other; right from their buggy operating system upgrades to Apple not providing power cable compatible to Indian market resulting in earthing issues. Out of frustration I jumped back to Ubuntu and now back on Windows after long years. 

Getting onto Windows was more out of necessity than interest and I started to explore how much things have changed in the Windows world. It wasn't a smooth return for me but the teething period is over and I'm loving Windows again. If you are onto Windows 10 Pro edition, and wanting to get the best of both worlds (Windows and Linux), this post is for you. I am jotting down ProTips to experience delight and productivity at development work.
  1. Use WSL 2 instead of WSL 1, for the former is far less resource intensive by integrating natively with Windows 10 Hyper-V virtualization stack, and thus phenomenally faster too. If you are on Windows 10 Home edition, you need to upgrade it to Windows 10 Pro edition and it is worth it, for you can get it at half the price upon upgrade.
  2. Do not mount windows native formatted drive (NTFS) onto WSL for code that can be developed both in WSL environment and Windows. While this works, it is snail paced and you will frustrated too soon. I tried this out of curiosity and frustrated beyond my anticipation. If you are still wanting this, you will have to first format the storage drive in DOS format (as FAT32), so that it works well with your WSL and host Windows operating systems. This is possible the best middle-ground that you can hit upon.
  3. Use Windows Terminal instead of  CmderConEmuMinttyCygwin or any other console emulators. Why? You can customize it with default settings for each of WSLs, Windows Command Prompt, Powershell or other terminals integrated with it. Also Windows Terminal is lightweight and faster.
  4. When you start your development server in WSL 2, try testing it in your browser with localhost, it won't work. WSL is one proper sandboxed environment or VM. You need to port forward localhost settings for this to work. This can be done by adding the line like below in your .wslconfig file in your windows $HOME directory.
    -- --
  5. WSL 2 can consume all of your host memory. You can set limits to it by appending the line memory=16GB in your .wslconfig file.
  6. Do install Oh-My-ZSH to use zsh shell instead of the default bash. You get bunch of goodies like pre-configured aliases for Git and more by way of its plugins that you can configure to your preference.
  7. If you are into using tmux, you can use that too in your WSL 2, and power it up with tmux-powerline.
  8. You can change the location of your WSL 2 distribution's virtual hard drive. I keep all of my VMs (and now WSL 2 virtual hard drives) in D:\VMs\<platform>\<distribution name>. Run the following commands in PowerShell - replacing distribution name and preferred location:
    ----
    Also at the time of writing, when you import a distribution, you may need to tell WSL 2 to start the distribution using the Linux user account you created when you first created the distribution. Thanks to 58bits.com that you can run the below PowerShell script that imports the distribution, and resets the default user as you would like it to be.
    -- --
    Note that if your import fails with 'Unspecified error' (or other) - you may need to limit the amount of memory allocated to vmmem. You can do this with WSL2 config to limit memory as mentioned in ProTip 5 above.
  9. If you are into using VS-Code as your IDE for development, you can launch the one you installed on your host Windows 10 OS from WSL 2 bash in your project's root folder and executing `code .`. With this you can work on your windows operating system launching your development servers in WSL environment, thus getting the best of both the worlds. Additionally, you can install your vs-code extensions on remote wsl as well as on host OS, all from within your IDE.
  10. And Docker Desktop for Windows works well with your WSL2 too. You just can extract the best from everything. 
Upcoming Feature: Having dual boot for Windows and Linux? You can mount your linux partitions onto WSL2 in Windows 10. Checkout Microsoft Dev Blogs

Windows 10 is super cool again with WSL 2. Whether you are a Windows buff wanting to leverage Linux goodies, or a Linux buff wanting to draw upon Windows 10 strengths, you can have it all. Happy coding!!..

References

September 5, 2020

Fix Timeout Error Connecting To MongoDB Atlas

 I am at the moment dabbling with Strapi, which is a headless CMS written using Javascript. I love MongoDB and a fanboy of managed services. Getting to know that MongoDB has launched MongoDB Atlas as a managed service for cloud, I wanted to give it a try.

I had configured Strapi to use MongoDB Atlas as its backend and it worked as expected. The configuration looked like below (note that it uses mongoose library as connector to work with MongoDB Atlas):

As I was working on Strapi in development mode (it restarts its server after code changes), the server restart failed with an error message like below:


My favorite Stackoverflow or MongoDB forum didn't come to my rescue this time. As it turns out, setting the srv to false and replacing the MongoDB Atlas service name with comma separated values of individual node's URI:PORT, worked. I really don't like to configure things this way, as the former is more elegant approach. But until things are set right at MongoDB Atlas (as I see it), this should serve as a workaround. The new MongoDB connection configuration looks like below:

Happy coding!!..

August 30, 2020

Multi-tenant Architectures

 


Multi-tenancy Application Deployment Architecture could be modeled in 4 broad ways:

  1. Separate Apps & Separate Databases
  2. Shared Apps & Shared Databases
  3. Separate Apps & Shared Databases
  4. Shared Apps & Separate Databases
There is no right or wrong here. It's about choice and consequence that you should consider taking into your business context and constraints. In this post I intend to jot down a some key points to keep in mind for each of these multi-tenant architecture. These are more of quick notes for my quick reference, a cheat-sheet of sorts when I have to make choices. And I guess this can come handy to you too in your wise decision making.

Separate Apps & Separate Databases

  • Easiest to implement from development and deployment stand-point.
  • Just automate the deployment infrastructure for every tenant for quick set-up.
  • Most expensive of all the models from infrastructure cost stand-point.
  • Relatively longer deployment time for newer application versions, at scale. 
  • More wastage from infrastructure resource utilization point of view.
  • The application's statelessness criteria for scalability would mean:
    • not holding user-request data
  • Suitability:
    • This is the best way to begin your SAAS platform until product-market fitment.
    • When you provide SAAS as white-labelled product.
    • When you deploy your SAAS product at client infrastructure, maybe for compliance reasons.
  • Challenges:
    • How do you optimize resources for cost?
    • Not succumbing to the temptation of having different code-bases for different tenants. Yielding to this temptation is like getting those easy financial loans at very high interest rates and with the notorious rider of terms and conditions, that is often overlooked blinded by dreams... just as in gambling houses. Often though, the gamblers here are the Product Management team and the losers that get publicly shamed are the development teams.

Shared Apps & Shared Databases

  • The most complex beast of all the multi-tenancy architectures. Depending on the magnitude of tech-debts and gap in the discipline of engineering management, the complexity often grows many-folds increasing the risks of product stability and scale.
  • Maximizing infra utilization every bit for maximum profitability. 
  • Challenges:  
    • How do you manage as volume of transactions  and data increases? The relational database by its virtue is vertically scalable and not horizontally scalable. Now this means it could become a bottleneck sooner than you think as you onboard more and more tenants, depending on the volume of transactions and data.
    • In case of SaaS apps that provides lot of customizations on the UI, how do you get this tenant specific configuration optimally for latency? Wix eCommerce, Shopify, etc.

Separate Apps & Shared Databases

  • A model where tenant specific configuration are tied to deployed instances, but all share a common database. The data isolation per client is achieved by prefixing database schema with tenant info. 
  • You got many web-frameworks and web-plugins supporting this model of prefixing-queries with tenant specific data, to hit the right datasource. For example, apartment (rails/ruby), multi-tenant (laravel/php), springboot (java), etc.
  • Relational database instances are expensive. It way pricier than your application instances and is not as disposable as your compute instances can are. You got to do a bit of forward looking into future for its capacity planning.
  • When you are managing your database instance as a SaaS provider and want to optimize on the overall cost, often the easiest thing to do is use shared database.
  • The application's statelessness criteria for scalability would mean:
    • not holding user-request data
    • not holding database-responses
  • Challenges: 
    • How do you manage as volume of transactions  and data increases? The relational database by its virtue is vertically scalable and not horizontally scalable. Now this means it could become a bottleneck sooner than you think as you onboard more and more tenants, depending on the volume of transactions and data.

Shared Apps & Separate Databases

  • A request can hit any of the available application instance.
  • Tenant specific configuration is got dynamically with every request.
  • The application's statelessness criteria for scalability would mean:
    • not holding user-request data
    • not holding tenant's configuration
    • not holding database-responses
  • Challenges: 
    • How do you hit the right database dynamically on a per request basis? How do you do it optimally for latency? Think  of Atlassian suite of products like Confluence, Jira, Bitbucket etc.
    • In case of SaaS apps that provides lot of customization on the UI, how do you get this tenant specific configuration optimally for latency? Wix eCommerce, Shopify, etc.

Hope that helps you in your design choice for your SAAS architecture...If your experience is otherwise from mine, or that you disagree with any of my points, do pour your thoughts and help me learn from your experience.