Updates from Madison Scott-Clary (Makyo) Toggle Comment Threads | Keyboard Shortcuts

  • Madison Scott-Clary (Makyo) 7:50 pm on January 3, 2018 Permalink | Reply  

    Accessing the Juju CLI from within the GUI 

    In the Juju GUI 2.11.1 release, we are excited to bring a new feature we’ve been working on for a while now: the shell in the GUI.

    The GUI is a powerful tool, but at times the command-line is necessary. For instance, the ability to SSH into a unit helps for debugging processes or accessing data directly. Running debug-hooks is another: if a unit is stopped during one of its hooks and you need to see if you can get it up and running, sometimes debug-hooks is your best bet.

    However, not all developer situations have the CLI available. If you’re accessing your environment from Windows, getting to the tools you need from the CLI isn’t trivial.

    To address these cases, we’ve developed the jujushell functionality.

    The shell in the GUI consists of a few different, parallel lines of work. The first is an update in the GUI. This adds the ability to connect to a jujushell server through the browser using the xterm.js library. This will give you a pane into which you can read and write from a terminal.

    The terminal itself is hosted through terminado, a means of providing a shell over a websocket connection. In this instance, the goal is to give access to a terminal running on a server.

    The server is, appropriately enough, a charm. When you deploy this charm to your environment, it will spin up a unit which you will connect to via terminado.

    Naturally, this would be a less than ideal situation in many respects. For one, it might not be secure to run the terminal directly on a unit. If you mess something up on the unit, it can be pretty easy to wind up in an error state in your environment.

    To this end, the shell is not structured to allow connecting to the unit itself, but to LXC containers spun up on the unit.

    These containers are simple and lightweight by design, taking up a minimum of ram, CPU, and disk space. They all have juju installed on them, of course, and as soon as one is spun up, you will have access to your environment. No additional work is needed. You’re already logged into your model from the GUI, so there is no need to log in from the shell, either.

    This connection is managed and proxied via the jujushell service itself. This is a simple service written in Go which will perform a handshake with the GUI, set up your LXC, and then start proxying your connection from the browser, through the unit, to the terminado service running within the container itself.

    That’s a lot of moving parts, but we’ve made it simple to set up.

    The first step is to bootstrap a controller. This will get you up and running with a default model. If you already have a non-JAAS controller, you can do this in one of your already existing models or a new model to play around in.

    Once your controller is bootstrapped, you can open the controller and log in with the address and credentials available from the juju gui command or provided to you by someone with the credentials.

    From within the GUI, search for the jujushell charm (for instance, cs:~juju-gui/jujushell) and deploy it. This will add the application to your model to connect to with the shell.

    Here is a setup done via the CLI following the same steps:

    CLI example

    Once this application is deployed, you will need to expose it and configure it.

    For the configuration you will need a DNS name. This is necessary to allow secure websockets. Internally, the charm uses Lets Encrypt to generate certs, which require a domain name. In the dns-name configuration setting, enter this domain (e.g: example.com).

    Configure the charm

    You will also need to set up your domain name with the IP address of the unit. This can be found in the inspector in the GUI by viewing the unit details.

    Setting up the domain

    Once you have configured and exposed your application, save your changes and click to commit the changes with the button at the bottom right of the GUI. Then, wait for the DNS to propagate and for the unit to be ready.

    At this point, the application is ready to serve Juju CLI sessions. Anyone connected to the controller can use the application, once they’ve set their GUI up to recognize the terminal.

    For this, you will need to open the GUI settings by typing shift+1. In the settings pane, enter in the DNS name for the service in the provided input (e.g: example.com), and click save.

    Setting up the shell address

    From there, you can switch to a model (or click back to the canvas), and you should see a new button appear in the header with a prompt icon.

    When clicked, all of the magic begins to happen. The websocket connection between the browser and the jujushell service is made, the service starts spinning up an LXC. This part may take a second, but once the container is set up, a shell prompt will appear, showing the name of the currently connected model.

    The shell

    There you have it, a shell into your model! From here, you can run juju any juju commands — try it out with juju status — and you’re ready to go.

  • Madison Scott-Clary (Makyo) 5:11 pm on August 13, 2015 Permalink | Reply  

    Bundles Bundles Bundles! 

    You’ve gone through the process of sorting through various service orchestration solutions, and settled on Juju, since it will work with your existing frameworks and solutions, such as chef, puppet, and ansible. You’ve gone ahead and charmed up a few of your microservices so that you can get them deployed to your Juju environment. You’ve searched through the charmstore to find the databases, load balancers, and additional charms that you need to really make your project shine.

    Whew! That’s gonna be a lot of docs to write for new hires, right?

    Not necessarily! Here’s where bundles come into play!

    Bundles allow you to pull all of your services, unit placements, and relations together into one YAML file. A bundle is basically an export of a Juju environment. In fact, if you use the Juju GUI, it literally is that: the GUI will export all of your services with all of their config values, all of the relations linking them together, and the way your units are placed on machines.

    Bundles – V3 vs V4

    First, a bit of an important note. Bundles have been around for a little while. Recent work, however, has meant that there are some changes in how bundles are structured. The older format, known as the V3 format (for the third version of the API), pulled multiple bundles together into a basket – this is no longer the case with the V4 API.

    For instance, you might have a few wordpress bundles pulled together into a basket like so:

      services: ...
      relations: ...
      series: trusty
      services: ...
      relations: ...
      series: trusty

    Since baskets are deprecated, trying to upload a basket to the charmstore now will result in that V3 series of bundles being migrated to individual V4 bundles.

    The second difference between the two bundles formats is that the V4 format allows a machine specification. This means that you can have a top-level machines entry in your bundle.yaml file. This will contain a list of machine objects, which can have constraints, series, and annotationsobjects, which allow you finer-grained control over your machines:

      - "0":
        constraints: {mem: 4096, cpu-cores: 2}
      - "1":
        annotations: {foo: bar}
        series: trusty
      - "2": {}

    Finally, the unit placement directives are different between the two formats. Previously, if you wanted to collocate two units, you would use a format unique to bundles, which used an equals sign to separate the name of the service from the unit number. With V4 bundles, however, you can simply use the unit syntax that you’re familiar with from working with juju.

      charm: ...
      num-units: 2
      charm: ...
      num-units: 2
        // collocate directly onto the machine that the first unit of service-1 is
        // on
        - service-1/0
        // collocate into an LXC container installed on the machine that the second
        // unit of service-1 is on
        - lxc:service-1/1

    It’s also worth noting that placement directives can specify machines in the machine specification. That way, you can deploy units of a service to a given machine, either directly to the machine itself or to an lxc or kvm container (if supported).

    This exposes one more difference between V3 and V4 bundles: in V3 bundles, the only machine you’re allowed to refer to is machine 0 (the bootstrap node), which allows you to place a service on the only machine guaranteed to be in your environment. You can do this in V4 bundles as well, but note that it is only possible if you do not have a machine spec in the bundle. This is because the system can’t be sure whether you mean the bootstrap node or the machine named “0” in the spec, so it defaults to placing it on the named machine (or erroring if there is no machine named “0”).

    For more information on the bundle format specifications and the difference between V3 and V4 bundles, please be sure to check out the bundle doc in the charmstore! This should be kept up to date, as the Juju charmstore matures.

    Creating bundles

    The easiest way to create a bundle is through the Juju GUI. This even works in sandbox mode, so you can use demo.jujucharms.com to create your ideal environment without having to spin up any machines. Simply deploy and configure your services, add relations, place your units, and commit your changes to the sandbox, then you can export the environment as a bundle YAML file.

    Bundle validation

    You can easily validate a bundle.yaml file by dragging it onto the Juju GUI canvas and ensuring that all of the services, units, relations, and machines are created just how you specified. As with services, bundles dragged onto the canvas are in an uncommitted state until you hit the commit button. This means you can test in both sandbox and live environment modes without spinning up machines.

    This works through a bit of magic called Juju bundlelib, which decomposes a bundle into a set of steps that will need to be undertaken to deploy all aspects of the bundle. Since this is a python utility that lives separate from the GUI, you can validate a bundle on the command line by running pip install jujubundlelib (in a virtualenv, if you wish), and then passing your bundle.yaml file as an argument to the command that it installs, getchangeset. If you have any errors in your bundle, the getchangeset command will enumerate the items that will need to be fixed; otherwise, it will output a JSON list of changes (the changeset) that your bundle produces.

    Deploying bundles

    There are a few ways to deploy bundles of charms. If you have the YAML file on your computer, you can drag that to the Juju GUI and the GUI will attempt to deploy the bundle for you by fetching the change set. This will leave all of the services, units, machines, and relations in an uncommitted state so that you can change anything you need to. Once you’re done, you can commit your changes to your environment.

    Another way to deploy your bundle is using Juju Quickstart. This will spin up an environment for you (if you haven’t already), deploy the specified bundle along with the GUI, and get everything up and running for you. By default, Quickstart uses the Juju Deployer, but if you pass the -u option, your changes will be uncommitted and shown to you in the GUI.

    You can also use the Juju Deployer on its own. It’s available on PyPI as well.

    Once you publish your bundle to Launchpad, you will be able to navigate to view it onjujucharms.com and deploy it from the charmstore as well.

    More information

    Make sure to check out the full documentation for bundles to see all that can be done with them!

  • Madison Scott-Clary (Makyo) 4:36 pm on July 6, 2015 Permalink | Reply  

    Juju GUI 1.4.1 – Now even less committal! 

    Just kidding.  We’re pretty committed to providing a really neat and useful visual front end to your juju environment.  This latest release mostly includes some fixes to the ways in which uncommitted bundles work.

    • Config values specified within bundles now behave as expected in the ghost inspector.
    • Still have some older, V3 bundles laying around?  Legacy support is now included for uncommitted bundles, so you can use the GUI as well as the deployer to send them to your environment.
    • While we’re on the note of the deployer, if you deploy a bundle through the deployer using juju-quickstart, you will once again receive notifications about the status of the deployment inside the GUI.
    • Plus: tons of code removed, just to help slim things down (bye-bye, pyjuju support); switching from LESS to SCSS for styling; and wrapping external modules in YUI wrappers so that we can combo-load them more easily.

    To upgrade an existing deployment:

    juju upgrade-charm juju-gui
    juju set juju-gui "juju-gui-source=1.4.1"

    To deploy fresh:

    juju deploy juju-gui

    If you would like to request other features, have any questions, or run into any bugs, you can find us…

    IRC: freenode.net #juju and #juju-gui
    Twitter: @jujuui
    Email: juju@lists.ubuntu.com
    Bugs: https://bugs.launchpad.net/juju-gui

  • Madison Scott-Clary (Makyo) 6:05 pm on January 14, 2015 Permalink | Reply  

    Juju GUI 1.3.0 Release 

    Yesterday, we released version 1.3.0 of the Juju GUI and the GUI charms.  This release comes with two new features that we’re all very excited about.

    Screenshot from 2015-01-14 10:43:23

    First, we’ve switched from using version 3 of the charmstore API to the brand new version 4, which means a big improvement in speed and usability.  This is the same charmstore that helps to drive jujucharms.com, and we’re all proud of the work that’s gone into making it fast, stable, and flexible.  This affects everything from charm icons, to charm and bundle details, to search results.

    Secondly, with the upcoming feature in Juju Core 1.21 of multiple users, we’ve added the ability to log in as any of the users that are attached to your environment.  Once you’ve created your environment in juju, you can add a user with:

    juju user add <username>

    Once the user has been created, you will be able to log in using that user from the login screen in the GUI.  Additionally, you will be able to change which user you are logged in as by logging out and logging back in as a different user.  You can run

    juju help user

    for more information.  Since older versions do not support logging in as different users, this functionality is locked down within the GUI charm so that it will only be available if your version of Juju can support it.  More work will be coming in future versions of Juju surrounding the use of multiple users in an environment, so be sure to keep an eye out!

    As always, you can keep up with our development on GitHub and file any issues with the GUI on Launchpad.  The charms (trusty and precise) are available on jujucharms.com.  If you’re already running the GUI version 1.2.5, you can upgrade it from the GUI or with:

    juju upgrade-charm juju-gui


  • Madison Scott-Clary (Makyo) 3:34 pm on March 14, 2014 Permalink | Reply

    Weekly Retrospective – Week of March 10 

    Jeff – every js file has a test file associated with it. We could entertain the
    idea of creating more descriptive subdirectories, within each subdir have tests
    folder, those tests would be responsible for the module in there. Lots of tests
    touch too much. Decentralizing tests could help us write better tests with more
    coverage. Benji bring sup that it makes grepping for things harder, but not so
    much as to be a -1. Rick: switching over could be expensive, and build step
    would need to be modified to account for that – investigate work involved.

    Monkey patch before/after – Jeff – If you don’t provide before/after, they won’t
    be monkey patched. Be aware that there’s no default call if you don’t include
    an afterEach for cleanup. There should be a bug to have a base afterEach that
    runs cleanups, or at least warns about that.

    Dropping charm on service block – Jeff and Matt – if you drag something onto the
    canvas and drop it on the service block it acts like dropping a file in the
    browser, leads to download. Should we bubble? Can we do an invisible overlay?
    Apparently not, there’s an issue with it working only in chrome. Decided on
    canvas only. Lets file it as a bug – if we can fix it, verify, but if we
    can’t, can we at least reject the drop? Investigate.

    Add deps into modules-debug – Jeff – Our loader file doesn’t parse nested
    requires, explicitly add module into the use section which is for a sub
    dependency. Add requires into modules-debug list to avoid recursion.

  • Madison Scott-Clary (Makyo) 5:00 pm on February 11, 2014 Permalink | Reply
    Tags: social, twitter   

    Just as a quick note, we’ve got a new Twitter feed to follow thanks to @mitechie! Check out @jujuui on Twitter for updates from the block and from GUI team members.

  • Madison Scott-Clary (Makyo) 5:17 pm on August 16, 2013 Permalink | Reply  

    Weekly notes Aug. 16 

    Dev environments don’t match charm production

    rick – bit on last release, 0.8 in prod, 0.10 in dev. How to avoid compiling,
    but also keeping that sort of inline
    jeff – dependency of dependency, contextify needs g++
    jeff – production has a weird imagemagick issue, building sprites, solution was
    to lock down node to 0.8. To resolve, update local dependencies, update node on
    the charm, make sure it deploys properly.
    rick – doesn’t match test environment.
    jeff – precompile and send with charm, gary disagrees – prebuilt assets
    rick – chase down why it needed to change
    ben and jeff – contextify needed? Need dev story for building non-release
    versions. Don’t really have a good answer beyond updating dependencies.
    rick – should be documented, wasn’t. Don’t mind stuff breaking so long as it
    also breaks in dev. No releases on friday!

    End: be aware that we have oddities that suck, but we should be upgrading
    dependencies to work in both environments


    jeff – styles don’t make sense, and kind of all over the place
    rick – done by Huw to standardize fonts, because they were all over the place.
    meaningful class names are probably not possible, and it is grepable
    jeff – at least a naming convention?
    rick – patches welcome, but probably no more fonts

    Service config

    jeff – whenever we need charm config details, they’re stored in one format and
    never used in that format – always parse them into another format. Input on
    changing formats in model so we don’t have to post-process
    ben/matt – it’s what juju sends (notably pyjuju)
    aaron – it’s stored different even in the api, mongo, elasticsearch
    jc – patches welcome!

    Existing problem all over the ecology

    failure messages to assertions

    jeff – should have failure messages due to number of assertions in a test, the
    expecting true to be false or undefined. Hard to tell without rerunning
    benji – because test runner doesn’t report line number
    rick – +1
    Curtis – +1, docstring in test gets printed out in python.
    matt – way forward?
    rick – reviewers look for it
    jeff – if test failure would be ambiguous, add a message

    IE10 mini retrospective

    tickets: all known issues are fix committed, though a few low-hanging fruit
    rick – takeaway: QA in IE10 – autocomplete good example
    matt – most branches, qa in ie10 for next few weeks, major features and releases from here on out

    scaling and target units

    jeff – target units only makes sense if we have target units stored somewhere in
    the bootstrap node. if user refreshes, number will be incorrect, though current
    units will be fine – ditto other users, won’t know where we’re scaling to.
    Core doesn’t support it, could be annotation on service, this is our target
    ben – more than just an interface decision, gui can’t do things cli can’t.
    jeff – scaling story is broken and buggy. Ongoing story, need design in on it
    ben – allocate resource, advocate core change (target unit in core)
    curtis – core has their own agenda that we have to take into account
    ben – next step is to get the right people in a conversation

  • Madison Scott-Clary (Makyo) 7:34 pm on August 14, 2013 Permalink | Reply  

    Sandbox mode for juju-core 

    The GUI relies heavily on a sandbox mode and fake backend that mimics all of the functionality of a Juju environment in memory within the browser. This is how the GUI runs on jujucharms.com, in fact, and it is how we do much of our development. To ensure that both the environments for juju-core and the older pyjuju are fully represented, each of these is present in a sandbox form. A branch has just landed (and will be available in the next release) which completes all of the required operations in the juju-core sandbox mode. This means that we now have a full-featured testing and devel environment for the GUI and core which does not require spinning up any machines!

    This is also the first step to implementing one of the newer features available in core that was not available in the older pyjuju: upgrading charms within a service.

  • Madison Scott-Clary (Makyo) 2:19 am on July 23, 2013 Permalink | Reply
    Tags: , , OpenStack   

    Deploying OpenStack with Juju and the GUI 

    A small video tutorial on how to deploy OpenStack with Juju using the GUI

  • Madison Scott-Clary (Makyo) 3:07 pm on July 1, 2013 Permalink | Reply
    Tags: environment view, , layout, services   

    Focusing on Services 

    At the heart of the Juju GUI environment view are the service blocks, which provide you with a quick overview at a glance of both how your environment is structured and how well things are going.  There has been some work done recently and more to come to help bring these more into focus and show the information needed to the user.

    Automatic service placement

    Prior to the ability to store a service’s position on the canvas in Juju, services were placed with a circle-packing algorithm which attempted to space them out appropriately.  This worked well for small environments but crowded larger environments together, and wound up being less than ideal.  Storing the positions helped alleviate this in some cases: one could drag services to where they made sense and have them stay there.  This doesn’t cover a read-only scenario, however, and so we’ve helped alleviate this problem by removing scaling from the pack layout, which caused larger environments to become cluttered. This allows all services to be positioned a good distance from each other, no matter the number of them on the canvas.

    Additionally, some work has been done around adding new services.  When a service was created before, it was run through the pack layout algorithm.  However, with just one service being placed, the algorithm always placed it in the center of the canvas.  Adding multiple services would result in them being stacked one on top of the other.  To solve this, new services are no longer run through the pack layout, but instead through an outside algorithm.  This means that, when adding a new service, the GUI will find the smallest polygon that can be drawn around all of the existing services (called the convex hull) and place the new service outside of that polygon.  This way, creating new services never places one service on top of another.


    A problem we ran into in some instances has to do with centering the services in the viewport.  SVGs are a coordinate plane: services are positioned absolutely with x and coordinates.  When the GUI first opens, it starts with the coordinates (0, 0) in the upper left hand corner of the viewport.  However, this means that if the services have been dragged outside of the viewport’s area on starting, the canvas will appear empty.  We used the convex hull algorithm again to help us out with this problem.  Once we have the polygon which contains all services, we can find its center of mass (called a centroid) and place that point at the center of the canvas.  All services will surround this point.

    This runs by default when the GUI starts up, so that the environment view is centered.  However, the GUI also centers the canvas when a new service is created.  Instead of passing all of the services, though, just the new one is passed to the centering code, which centers the newly created service in the viewport.  If you ever pan away from your services by accident, you can re-center them by hitting ‘)’ (Shift+0).

    We’re continually working to improve the environment view to make it more readable and usable, finding the right balance of information to expose up front without providing an arcane or confusing graph.  Focusing on the services which make up the environment is a big part of that, and we’re working to make that the best experience possible.

Compose new post
Next post/Next comment
Previous post/Previous comment
Show/Hide comments
Go to top
Go to login
Show/Hide help
shift + esc