feat: Migrate maas.io to /maas (#1772)

* feat: Migrate maas.io to /maas

* Fix linters

* Address review comments

* fix: Don't perge venbox styles

* fix: Address review comments

* fix: Remove brokenn link from /resources
This commit is contained in:
Peter French
2025-07-11 10:32:13 +02:00
committed by GitHub
parent e682320cc6
commit 33810b3cd7
21 changed files with 3692 additions and 4 deletions

View File

@ -39,7 +39,8 @@
"react-dom": "^18.2.0",
"sass": "1.89.2",
"uuid": "^11.1.0",
"vanilla-framework": "4.24.1"
"vanilla-framework": "4.24.1",
"venobox": "2.1.8"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",

View File

@ -21,6 +21,7 @@ let config = {
"static/*.xml",
"node_modules/flickity/dist/flickity.pkgd.min.js",
"node_modules/leaflet/dist/leaflet.js",
"node_modules/venobox/dist/venobox.min.js",
],
defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
safelist: {
@ -31,6 +32,8 @@ let config = {
/^u-/, // Utility classes
/^js-/, // JavaScript-related classes
/^leaflet-/, // Leaflet classes for map
/^vbox-/, // VenoBox classes
/^venobox/, // VenoBox classes
],
greedy: [
/^iti/,

View File

@ -24,3 +24,6 @@ cp node_modules/flickity/dist/flickity.pkgd.min.js static/js/modules/flickity
mkdir -p static/js/modules/leaflet
cp node_modules/leaflet/dist/leaflet.js static/js/modules/leaflet
mkdir -p static/js/modules/venobox
cp node_modules/venobox/dist/venobox.min.js static/js/modules/venobox/venobox.min.js

View File

@ -313,4 +313,26 @@ automotive:
children:
- title: Overview
path: /solutions/automotive
path: /solutions/automotive
maas:
title: MAAS
path: /maas
children:
- title: Overview
path: /maas
- title: How it works
path: /maas/how-it-works
- title: Install
path: /maas/docs/how-to-get-maas-up-and-running
- title: Docs
path: /maas/docs
- title: Features
path: /maas/tour
- title: Tutorials
path: /maas/tutorials
- title: Blog
path: /maas/blog
- title: Forum
path: https://discourse.maas.io/

View File

@ -0,0 +1,249 @@
// This file contains styles specific to the /maas bubble.
// They were copied over from maas.io and can be removed once rebranding is complete.
@use "sass:math";
@mixin maas-styles {
.p-heading-icon-block {
align-items: flex-start;
display: flex;
flex-wrap: wrap;
width: 100%;
@media only screen and (min-width: $breakpoint-large) {
margin-bottom: 2rem;
}
}
.p-heading-icon-block__copy-block {
margin-top: -0.5rem;
}
.p-heading-icon-block__icon {
border-radius: 0;
height: auto;
margin-bottom: $spv--small;
margin-right: $sph--large;
padding-right: $sph--large;
width: ($sp-unit * 5) + $sph--large;
}
.p-sidenav__body {
// Fix p-sidebar-nav to understand
// h3 headings, and not require any classes on the <ul>s and <li>s
// Because the markup is pulled directly in from Discourse
padding: math.div($sp-large, 2) $sp-large;
a,
a:visited {
color: $color-dark;
text-decoration: none;
}
a:hover {
color: $color-link;
text-decoration: underline;
}
.is-active {
position: relative;
&::before {
background-color: $color-mid-light;
bottom: -0.25rem;
content: "";
left: -1rem;
position: absolute;
top: -0.25rem;
width: 0.1875rem;
}
}
ul {
margin-bottom: 0.625rem;
margin-left: 0;
padding-left: 1rem;
}
li {
padding-bottom: 0.125rem;
padding-top: 0.125rem;
}
h3 {
font-size: 1rem;
font-weight: 400;
line-height: 2;
margin: 0;
padding: 0;
}
}
.p-takeunder {
border-radius: 0.125rem;
margin-right: -1 rem;
padding: $sp-x-large;
@media only screen and (min-width: $breakpoint-large) {
padding: $sp-x-large $sp-medium $sp-medium $sp-medium;
}
&.is-dark {
color: $color-x-light;
a:link,
a:visited {
color: $color-x-light;
}
}
&.is-light {
color: $color-dark;
a:link,
a:visited {
color: $color-dark;
}
}
& + & {
@media only screen and (max-width: $breakpoint-large) {
margin-top: $spv--large;
}
}
}
.p-tutorial-section {
display: none;
&:target {
display: block;
}
}
.p-tutorials-meter {
background-image: url("#{$assets-path}77d5aee3-maas-difficulty-meter.svg");
background-position-x: -75px;
background-position-y: center;
background-repeat: no-repeat;
display: inline-block;
height: $sp-large;
margin-left: $sp-xx-small;
text-indent: -9999px;
width: 74px;
}
.p-tutorials-meter--1 {
background-position-x: -60px;
}
.p-tutorials-meter--2 {
background-position-x: -45px;
}
.p-tutorials-meter--3 {
background-position-x: -30px;
}
.p-tutorials-meter--4 {
background-position-x: -15px;
}
.p-tutorials-meter--5 {
background-position-x: 0;
}
.p-tutorial-section__footer {
margin-bottom: $sp-medium;
}
.p-tutorial__bug-link {
position: relative;
top: -1.38rem;
@media only screen and (min-width: $breakpoint-small) {
top: 0;
}
}
.p-tutorial__duration {
margin-bottom: $sp-small;
@media only screen and (min-width: $breakpoint-small) {
display: inline-block;
margin-bottom: 0;
margin-right: $sp-medium;
}
}
.p-tutorial__pagination {
@media only screen and (min-width: $breakpoint-small) {
display: inline-block;
}
}
%p-tutorial-pagination-item {
display: inline-block;
margin-right: $sp-small;
max-width: $sp-xxxx-large;
&:last-child {
margin-right: 0;
}
@media only screen and (max-width: $breakpoint-small) {
width: auto;
}
}
.p-tutorial__pagination-item--prev {
@extend %p-tutorial-pagination-item;
.p-icon--chevron-down {
transform: rotate(90deg);
}
}
.p-tutorial__pagination-item--next {
@extend %p-tutorial-pagination-item;
.p-icon--chevron-down {
transform: rotate(-90deg);
}
}
.p-tutorial__feedback-icon {
cursor: pointer;
}
.p-tutorial__feedback-options {
.p-inline-list__item {
.has-color {
display: none;
}
&:hover {
.p-tutorial__feedback-icon {
display: none;
}
.has-color {
display: inline-block;
}
}
}
}
.p-sidenav__toggle {
background-size: $sp-medium;
cursor: pointer;
float: right;
padding: $sp-x-large;
}
.p-blog-card--maas {
@extend %p-card--highlighted;
border-top: 3px solid rgb(233 84 32);
}
}

View File

@ -5,6 +5,7 @@
@include canonical-p-strip-suru-background;
@include canonical-p-strip-whitesuru;
@include canonical-p-strip-suru-blog-header;
@include maas-p-strip--dark;
.p-strip--light {
&.is-x-shallow {
@ -299,3 +300,67 @@
position: relative;
}
}
@mixin maas-p-strip--dark {
$color-suru-grey-1: rgba(216 216 216 / 54%);
$color-suru-grey-2: rgba(228 228 228 / 54%);
$color-suru-grey-3: #333;
$color-suru-grey-4: #262626;
$color-suru-grey-5: #171717;
$color-suru-grey-6: #181818;
$color-suru-grey-7: #2d2d2d;
$color-suru-grey-8: #383838;
$color-suru-grey-9: #2e2e2e;
$color-suru-grey-10: #393939;
.p-takeover--dark {
background-blend-mode: multiply, multiply, normal, normal;
background-color: $color-dark;
background-image: linear-gradient(
to bottom left,
$color-suru-grey-1 0,
$color-suru-grey-1 49.9%,
transparent 50%
),
linear-gradient(
to bottom right,
$color-suru-grey-2 0,
$color-suru-grey-2 49.9%,
transparent 50%
),
linear-gradient(
to top left,
$color-x-light 0%,
$color-x-light 49.3%,
transparent 50%,
transparent 100%
),
linear-gradient(
201deg,
$color-suru-grey-3 0%,
$color-suru-grey-4 46%,
$color-dark 90%
);
background-position: top right, top left, right bottom -1px, left top;
background-repeat: no-repeat;
background-size: 74% 99.83%, 68% 91%, 103.8% 20.26%, 100% 99.8%;
color: $color-x-light;
margin: 0;
padding-bottom: 11rem;
padding-top: 6rem;
}
.p-takeover--no-overlays {
// copy of ubuntu.com's .p-takeover--compliance found at https://ubuntu.com/takeovers
background-image: linear-gradient(
44deg,
$color-suru-grey-5 0%,
$color-suru-grey-6 9%,
$color-suru-grey-4 34%,
$color-suru-grey-7 67%,
$color-suru-grey-8 88%,
$color-suru-grey-9 100%,
$color-suru-grey-10 100%
);
}
}

View File

@ -0,0 +1,238 @@
@mixin pattern-venobox {
$color-modal-overlay: rgba($color-x-dark, 0.85);
$color-modal-controls: rgba($color-x-dark, 0.2);
.venobox {
width: auto;
&--expand {
margin: 0 auto 20px;
overflow: visible;
position: relative;
> img {
margin: 0 auto;
}
&::after {
background: {
color: $color-dark;
image: url("#{$assets-path}495995ef-fullscreen-white.svg");
position: center;
repeat: no-repeat;
size: 50%;
}
bottom: 15px;
box-shadow: 0 5px 10px 0 $color-modal-controls;
content: "";
display: block;
height: 20px;
position: absolute;
right: 15px;
width: 20px;
}
}
}
// venobox.css
.vbox-overlay *,
.vbox-overlay *::before,
.vbox-overlay *::after {
box-sizing: border-box;
}
// overlay: change here background color and opacity ----- */
.vbox-overlay {
$color-modal-overlay: rgba($color-x-dark, 0.85);
align-items: center;
background: $color-modal-overlay;
bottom: 0;
display: flex;
height: auto;
left: 0;
margin-top: 0;
opacity: 0;
overflow-x: hidden;
overflow-y: auto;
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
}
// preloader - choose between CIRCLE, IOS, DOTS, QUADS
@keyframes playload {
from {
background-position: 0;
}
to {
background-position: -576px;
}
}
// navigation
.vbox-close {
background: url("#{$assets-path}89c10794-remove.svg") no-repeat;
background-position: center;
background-size: 30%;
color: $color-x-light;
cursor: pointer;
display: block;
height: 100px;
overflow: hidden;
padding: 20px;
position: fixed;
right: 0;
text-indent: -100px;
top: 20px;
width: 100px;
@media screen and (max-width: $breakpoint-large) {
background-position: top 20px right 20px;
}
}
.vbox-next,
.vbox-prev {
background-color: $color-modal-controls;
border: solid transparent; // Using border instead of padding to keep bg image in place
box-sizing: content-box;
color: $color-x-light;
cursor: pointer;
height: 170px;
margin-top: -85px;
overflow: hidden;
position: fixed;
text-indent: -100px;
top: 50%;
width: 30px;
}
.vbox-prev {
background-image: url("#{$assets-path}f4e0a44f-icon-arrow-left-white.svg");
background-position: center left 15px;
background-repeat: no-repeat;
border-width: 0 30px 0 10px;
left: 0;
}
.vbox-next {
background-image: url("#{$assets-path}9e5e9f6f-icon-arrow-right-white.svg");
background-position: center right 15px;
background-repeat: no-repeat;
border-width: 0 10px 0 30px;
right: 0;
}
.vbox-title {
background: $color-dark;
bottom: 0;
color: $color-x-light;
float: left;
font-size: 1rem;
height: auto;
left: 0;
line-height: 28px;
overflow: hidden;
padding: 40px;
position: fixed;
text-align: center;
width: 100%;
@media screen and (max-width: 1024px) {
bottom: 25px;
}
}
.vbox-num {
background: $color-dark;
color: $color-x-light;
cursor: pointer;
display: none;
font-size: 12px;
height: 40px;
left: 0;
line-height: 28px;
overflow: hidden;
padding: 6px 10px;
position: fixed;
top: -1px;
}
// inline window
.vbox-inline {
background: $color-x-light;
height: 315px;
margin: 0 auto;
overflow: auto;
padding: 10px;
text-align: left;
width: 420px;
}
// Video & iFrames window
.venoframe {
border: 0;
height: 100%;
min-height: 600px;
width: 100%;
}
@media (max-width: 992px) {
.venoframe {
height: 480px;
min-height: inherit;
width: 640px;
}
}
@media (max-width: 767px) {
.venoframe {
height: 315px;
min-height: inherit;
width: 420px;
}
}
@media (max-width: 460px) {
.vbox-inline {
width: 100%;
}
.venoframe {
height: 260px;
min-height: inherit;
width: 100%;
}
}
// PLease do NOT edit this! (or do it at your own risk)
.vbox-open {
overflow: hidden;
}
.vbox-container {
margin: 0 auto;
max-width: 1200px;
padding: 0 15px;
position: relative;
width: 100%;
}
.vbox-content {
float: left;
overflow: hidden;
position: relative;
text-align: center;
width: 100%;
}
.vbox-container img {
height: auto;
max-width: 100%;
}
}

View File

@ -34,6 +34,8 @@ $p-small-lh-diff: map-get($line-heights, default-text) -
@import "pattern_tabs";
@import "pattern_homepage-modal";
@import "pattern_homepage";
@import "pattern_venobox";
@import "maas_styles";
@include vanilla;
@include vf-p-icon-status-waiting;
@ -62,6 +64,8 @@ $p-small-lh-diff: map-get($line-heights, default-text) -
@include canonical-p-navigation-mobile;
@include sprint-carousel;
@include homepage-styles;
@include pattern-venobox;
@include maas-styles;
@media screen and ($breakpoint-large <= width) {
.p-section__u-no-padding--top {

View File

@ -93,7 +93,7 @@
<div class="p-section--shallow">
<h1>{{ article.title.rendered|safe }}</h1>
</div>
{% if tags %}
<div class="p-section--shallow">
{% for tag in tags %}
@ -103,7 +103,7 @@
{% endfor %}
</div>
{% endif %}
<ul class="p-inline-list">
<span class="p-text--default">Share on:</span>
<li class="p-inline-list__item">

View File

@ -0,0 +1,251 @@
{% extends "base_index.html" %}
{% set active_section = "tutorials" %}
{% block page_title %}| {{ document["title"] }}{% endblock %}
{% block content %}
<section class="p-strip--image is-shallow"
style="background-image: url('https://assets.ubuntu.com/v1/e54487e2-maas-docs-suru.png')">
<div class="u-fixed-width">
<h1 class="p-heading--2 u-no-margin--bottom">{{ document["title"] }}</h1>
</div>
</section>
<div class="l-docs-wrapper">
<div class="l-docs">
<aside class="l-docs-sidebar" id="navigation">
<i class="p-sidenav__toggle p-icon--menu u-hide--medium u-hide--large"></i>
<nav class="p-sidenav__body u-hide--small">
<ol class="p-tutorial__nav">
{% for section in document.sections %}
<li class="p-tutorial__nav-item">
<p class="p-tutorial__nav-title u-no-margin--bottom">
<a href="#{{ loop.index }}-{{ section['slug'] }}"
class="p-tutorial__nav-link">{{ loop.index }}. {{ section["title"] }}</a>
</p>
</li>
{% endfor %}
</ol>
</nav>
</aside>
<div class="l-docs-content">
<div class="p-strip is-shallow">
<div class="l-docs-row">
{% for section in document.sections %}
<section class="p-tutorial-section"
id="{{ loop.index }}-{{ section['slug'] }}">
<h2 class="p-heading--3">{{ loop.index }}. {{ section["title"] }}</h2>
<article class="p-tutorial-section__content">{{ section.content | safe }}</article>
{% if loop.last %}
<div class="p-tutorial__feedback-options">
<p>Was this tutorial useful?</p>
<ul class="p-inline-list">
<li class="p-inline-list__item">
<img class="p-tutorial__feedback-icon"
src="https://assets.ubuntu.com/v1/aca5f600-Helpful-yes.svg"
alt="Positive response"
data-feedback-value="positive" />
<img class="p-tutorial__feedback-icon has-color"
src="https://assets.ubuntu.com/v1/784c0dc9-Helpful-yes-green.svg"
alt=""
data-feedback-value="positive" />
</li>
<li class="p-inline-list__item">
<img class="p-tutorial__feedback-icon"
src="https://assets.ubuntu.com/v1/5dacff00-Helpful-unsure.svg"
alt="Neutral response"
data-feedback-value="neutral" />
<img class="p-tutorial__feedback-icon has-color"
src="https://assets.ubuntu.com/v1/b601b52c-Helpful-unsure-orange.svg"
alt=""
data-feedback-value="neutral" />
</li>
<li class="p-inline-list__item">
<img class="p-tutorial__feedback-icon"
src="https://assets.ubuntu.com/v1/4ff77e8e-Helpful-no.svg"
alt="Negative response"
data-feedback-value="negative" />
<img class="p-tutorial__feedback-icon has-color"
src="https://assets.ubuntu.com/v1/b45bf2a3-Helpful-no-red.svg"
alt=""
data-feedback-value="negative" />
</li>
</ul>
</div>
<div class="p-tutorial__feedback-result p-notification--positive u-hide">
<p class="p-notification__content">Thank you for your feedback.</p>
</div>
{% endif %}
<hr class="u-sv3" />
<footer class="p-tutorial-section__footer row u-no-padding--left u-no-padding--right">
<div class="col-6 col-small-2 col-medium-3 u-vertically-center">
<a class="p-tutorial__bug-link"
href="https://discourse.maas.io{{ document.topic_path }}">
<small>Suggest changes&nbsp;&rsaquo;</small>
</a>
</div>
<div class="col-6 col-small-2 col-medium-3 u-align--right">
<div class="p-tutorial__duration">
<small>
<span class="u-hide--small">about</span>
{% if section["remaining_duration"] %}
{{ section["remaining_duration"] }}
{% else %}
0
{% endif %}
minutes to go
</small>
</div>
<div class="p-tutorial__pagination">
{% if loop.first %}
<button class="p-tutorial__pagination-item--prev p-button has-icon u-no-margin--bottom"
disabled
style="margin-right: 1rem">
<i class="p-icon--chevron-down">Previous step</i>
</button>
{% else %}
<a href="#{{ loop.index - 1 }}-{{ loop.previtem['slug'] }}"
class="p-tutorial__pagination-item--prev p-button has-icon u-no-margin--bottom"
style="margin-right: 1rem">
<i class="p-icon--chevron-down">Previous step</i>
</a>
{% endif %}
{% if loop.last %}
<button class="p-tutorial__pagination-item--next p-button has-icon u-no-margin--bottom"
disabled>
<i class="p-icon--chevron-down">Next step</i>
</button>
{% else %}
<a href="#{{ loop.index + 1 }}-{{ loop.nextitem['slug'] }}"
class="p-tutorial__pagination-item--next p-button has-icon u-no-margin--bottom">
<i class="p-icon--chevron-down">Next step</i>
</a>
{% endif %}
</div>
</div>
</footer>
</section>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<!-- end of tutorial feedback -->
<script>
(function() {
var tutorialFeedbackOptions = document.querySelector('.p-tutorial__feedback-options');
var tutorialFeedbackIcons = document.querySelectorAll('.p-tutorial__feedback-icon');
var tutorialFeedbackResult = document.querySelector('.p-tutorial__feedback-result');
[].forEach.call(tutorialFeedbackIcons, function(icon) {
icon.addEventListener('click', function(e) {
var feedbackValue = e.target.getAttribute('data-feedback-value');
dataLayer.push({
'event': 'GAEvent',
'eventCategory': 'feedback',
'eventAction': feedbackValue,
'eventLabel': feedbackValue,
'eventValue': undefined
});
tutorialFeedbackOptions.classList.add('u-hide');
tutorialFeedbackResult.classList.remove('u-hide');
});
});
})();
</script>
<script>
(function() {
function setActiveLink(navigationItems) {
[].forEach.call(navigationItems, function(item) {
var link = item.querySelector('.p-tutorial__nav-link');
if (link.getAttribute('href') === window.location.hash) {
item.classList.add('is-active');
} else {
item.classList.remove('is-active');
}
});
};
var navigationItems = document.querySelectorAll('.p-tutorial__nav-item');
var toggleButton = document.querySelector('.p-tutorial__nav-toggle');
setActiveLink(navigationItems);
window.addEventListener('hashchange', function(e) {
e.preventDefault();
setActiveLink(navigationItems);
});
sectionIds = [];
var tutorialSections = document.querySelectorAll('.p-tutorial__content section');
[].forEach.call(tutorialSections, function(section) {
sectionIds.push(section.id);
});
// Navigate to first tutorial step on load if no URL hash
if (!window.location.hash) {
var firstSectionLink = document.querySelector('.p-tutorial__nav-link');
window.location.hash = firstSectionLink.getAttribute('href');
} else {
// Redirect #0, #1 etc. to the correct section
match = window.location.hash.match(/^#(\d+)$/);
if (match) {
index = parseInt(match[1]);
sectionId = sectionIds[index];
window.location.hash = '#' + sectionId;
window.location.reload();
}
}
})();
</script>
<script>
(function() {
var polls = document.querySelectorAll('.poll');
[].forEach.call(polls, function(poll) {
var answers = poll.querySelectorAll('[type="radio"]');
var pollId = poll.getAttribute('data-poll-name');
[].forEach.call(answers, function(answer) {
answer.addEventListener('change', function(e) {
var answerLabel = document.querySelector('label[for="' + e.target.id + '"]');
var eventLabel = answerLabel.innerText;
var eventAction = document.getElementById(pollId).innerText;
dataLayer.push({
'event': 'GAEvent',
'eventCategory': 'survey',
'eventAction': eventAction,
'eventLabel': eventLabel,
'eventValue': undefined
});
});
});
});
})();
</script>
<script>
(function() {
var toggle = document.querySelector('.p-sidenav__toggle');
var sidebarContent = document.querySelector('.p-sidenav__body');
toggle.addEventListener('click', function(e) {
toggle.classList.toggle('p-icon--menu');
toggle.classList.toggle('p-icon--close');
sidebarContent.classList.toggle('u-hide--small');
});
})();
</script>
{% endblock %}

View File

@ -0,0 +1,105 @@
{% extends "base_index.html" %}
{% block page_title %}Contact us{% endblock %}
{% block meta_copydoc %}
https://docs.google.com/document/d/12zxzauq9GV6NYVTeKCCqtwMpflRGZewE5fdTg1SZoOQ/edit
{% endblock meta_copydoc %}
{% block content %}
<section class="p-strip--image is-dark p-takeover--no-overlays">
<div class="row">
<div class="col-8">
<h1 itemprop="description">Contact Canonical</h1>
<p class="p-heading--4">
Are you interested in adopting MAAS for enterprise use or partner with Canonical? Just fill in the form below and a member of our team will be in touch within one working day.
</p>
</div>
<div class="p-card col-4 u-no-margin--bottom is-light">
<h3 class="p-card__title">Looking for a little professional support?</h3>
<p>If you are a small organisation, you can purchase packs of Ubuntu Pro in our shop.</p>
<p>
<a href="https://buy.ubuntu.com"
onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'External link', 'eventAction' : 'Click', 'eventLabel' : 'Visit the Ubuntu Pro shop' });">Visit the Ubuntu Pro shop</a>
</p>
</div>
</div>
\
</section>
<section class="p-strip--light is-deep">
<div class="row">
<div class="col-8">
<!-- MARKETO FORM -->
<script src="https://assets.ubuntu.com/v1/37b1db88-jquery.min.js"></script>
<script src="https://assets.ubuntu.com/v1/d55f58bb-jquery.validate.js"></script>
<form action="https://ubuntu.com/marketo/submit"
method="post"
id="mktoForm_1337">
<ul class="p-list">
<li>
<label for="firstName" class="is-required">First name:</label>
<input required id="firstName" name="firstName" maxlength="255" type="text" />
</li>
<li>
<label for="lastName" class="is-required">Last name:</label>
<input required id="lastName" name="lastName" maxlength="255" type="text" />
</li>
<li>
<label for="company" class="is-required">Company:</label>
<input required id="company" name="company" maxlength="255" type="text" />
</li>
<li>
<label for="email" class="is-required">Work email:</label>
<input required id="email" name="email" maxlength="255" type="email" />
</li>
<li>
<label for="phone" class="is-required">Phone number:</label>
<input required id="phone" name="phone" maxlength="255" type="tel" />
</li>
{% include "shared/forms/_country.html" %}
<li>
<label for="Comments_from_lead__c" class="is-required">What would you like to talk to us about?</label>
<textarea required
id="Comments_from_lead__c"
name="Comments_from_lead__c"
rows="5"
maxlength="2000"></textarea>
</li>
<li>
<input id="canonicalUpdatesOptIn"
name="canonicalUpdatesOptIn"
type="checkbox"
value="yes" />
<label for="canonicalUpdatesOptIn">
I agree to receive information about Canonical&rsquo;s products and services.
</label>
</li>
<li class="u-sv3">
In submitting this form, I confirm that I have read and agree to <a href="https://www.ubuntu.com/legal/dataprivacy/contact"
target="_blank">Canonical&rsquo;s Privacy Notice</a> and <a aria-label="Read the Canonical privacy policy"
target="_blank"
href="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy">Privacy Policy</a>.
</li>
<li>
<button type="submit"
class="p-button--positive"
onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Internal link', 'eventAction' : 'Click', 'eventLabel' : 'Submit contact us' });">
Submit
</button>
</li>
<input type="hidden" name="formid" value="1337" />
<input type="hidden" name="returnURL" value="/maas#success" />
</ul>
</form>
<script src="https://assets.ubuntu.com/v1/f97fa297-stateCountry.js"></script>
<!-- /MARKETO FORM -->
</div>
</div>
</section>
{% endblock %}

View File

@ -0,0 +1,327 @@
{% extends "base_index.html" %}
{% block page_class %}docs{% endblock page_class %}
{% set is_docs = True %}
{% block body %}
{% macro create_navigation(nav_items, expandable=False, expanded=False) %}
{% if request.path == '/docs/api' %}
{% set expanded = False %}
{% endif %}
<ul class="p-side-navigation__list">
{% for element in nav_items %}
<li class="p-side-navigation__item">
{% if element.navlink_href %}
<a
class="p-side-navigation__link {% if expandable and element.children %}is-expandable{% endif %}"
href="{{ element.navlink_href }}"
{% if expandable and element.children %}aria-expanded={% if expanded or element.is_active %}"true"{% else %}"false"{% endif %}{% endif %}
{% if element.is_active and not element.navlink_fragment %}aria-current="page"{% endif %}
>{{ element.navlink_text }}</a>
{% else %}
<strong
class="p-side-navigation__text {% if expandable and element.children %}is-expandable{% endif %}"
{% if expandable and element.children %}aria-expanded={% if expanded %}"true"{% else %}"false"{% endif %}{% endif %}
{% if element.is_active %}aria-current="page"{% endif %}
>{{ element.navlink_text }}</strong>
{% endif %}
{% if expandable %}
{% if element.children %}
<button class="p-side-navigation__expand" aria-expanded={% if element.is_active or element.has_active_child %}"true"{% else %}"false"{% endif %} aria-label="show submenu for {{ element.navlink_text }}"></button>
{% endif %}
{{ create_navigation(element.children, expandable, element.is_active or element.has_active_child) }}
{% else %}
{% if element.children %}
{{ create_navigation(element.children, expandable) }}
{% endif %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endmacro %}
<div class="l-docs">
<div class="l-docs__header">
{% include "includes/header.html" %}
<section id="search-docs" class="p-strip--light is-shallow is-bordered l-docs__subgrid">
<div class="l-docs__main">
<div class="row">
<form class="p-search-box u-no-margin--bottom" action="/docs/search">
<input type="search" class="p-search-box__input" name="q" {% if query %}value="{{ query }}"{% endif %} placeholder="Search documentation" required/>
<button type="reset" class="p-search-box__reset" alt="reset"><i class="p-icon--close">Close</i></button>
<button type="submit" class="p-search-box__button" alt="search"><i class="p-icon--search">Search</i></button>
</form>
</div>
</div>
</section>
</div>
<div class="l-docs__sidebar">
<div class="l-docs__sticky-container">
{% if versions | length > 1 %}
<label for="version-select" class="u-hide">Version</label>
<select name="version-select" id="version-select" onChange="window.location.href=this.value">
{% for version in versions %}
{% set active = docs_version == version['path'] %}
<option value="{{ version_paths[version['path']] }}"{% if active %} selected{% endif %}>{{ version['version'] }}</option>
{% endfor %}
</select>
{% endif %}
<nav data-js="navigation" class="p-side-navigation" id="{{ navigation['path'] or 'default' }}" style="margin-top: 0.5rem">
<div class="u-fixed-width">
<a href="#{{ navigation['path'] or 'default' }}" class="p-side-navigation__toggle js-drawer-toggle" aria-controls="{{ navigation['path'] or 'default' }}">
Toggle side navigation
</a>
</div>
<div class="p-side-navigation__overlay js-drawer-toggle" aria-controls="{{ navigation['path'] or 'default' }}"></div>
<div class="p-side-navigation__drawer">
<div class="p-side-navigation__drawer-header">
<a href="#" class="p-side-navigation__toggle--in-drawer js-drawer-toggle" aria-controls="{{ navigation['path'] or 'default' }}">
Toggle side navigation
</a>
</div>
{% for nav_group in navigation.nav_items %}
{% if not nav_group.hidden %}
{% if nav_group.navlink_text %}
{% if nav_group.navlink_href %}
<h3 class="p-side-navigation__heading--linked">
<a class="p-side-navigation__link" href="{{ nav_group.navlink_href }}" {% if nav_group.is_active %}aria-current="page"{% endif %}>
{{ nav_group.navlink_text }}
</a>
</h3>
{% else %}
<h3 class="p-side-navigation__heading">{{ nav_group.navlink_text }}</h3>
{% endif %}
{% endif %}
{#
Use `create_navigation(nav_group.children)` for a default, fully expanded navigation.
Use `create_navigation(nav_group.children, expandable=True)` for the nested nav levels to expand only when parent page is active.
#}
{{ create_navigation(nav_group.children, expandable=True) }}
{% endif %}
{% endfor %}
</div>
</nav>
</div>
</div>
<div class="l-docs__title">
<div class="p-section--shallow">
<div class="u-fixed-width">
{% block title %}{% endblock %}
</div>
</div>
</div>
{% if document is defined and document.headings_map is defined and document.headings_map|length > 0 %}
<div class="l-docs__meta">
<div class="l-docs__sticky-container">
<aside class="p-table-of-contents">
<div class="p-table-of-contents__section">
<h4 class="p-table-of-contents__header">On this page</h4>
<nav class="p-table-of-contents__nav" aria-label="Table of contents">
<ul class="p-table-of-contents__list">
{% for heading in document.headings_map %}
<li class="p-table-of-contents__item"><a class="p-table-of-contents__link" href="#{{ heading.heading_slug }}">{{ heading.heading_text }}</a></li>
{% if heading.children %}
<ul class="p-table-of-contents__list">
{% for child in heading.children %}
<li class="p-table-of-contents__item"><a href="#{{ child.heading_slug }}" class="p-table-of-contents__link">{{ child.heading_text }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</ul>
</nav>
</div>
</aside>
</div>
</div>
{% endif %}
{% block content %}{% endblock content %}
<div class="l-docs__footer">
{% include "includes/footer.html" %}
</div>
</div>
{% block js_extra %}
<script src="/static/js/highlight.pack.js"></script>
<script>
hljs.initHighlightingOnLoad();
window.addEventListener("DOMContentLoaded", function() {
// Based on Vanilla side navigation example
// Should be moved out from the template as part of a given project JS
/**
Toggles the expanded/collapsed classed on side navigation element.
@param {HTMLElement} sideNavigation The side navigation element.
@param {Boolean} show Whether to show or hide the drawer.
*/
function toggleDrawer(sideNavigation, show) {
const toggleButtonOutsideDrawer = sideNavigation.querySelector(
".p-side-navigation__toggle"
);
const toggleButtonInsideDrawer = sideNavigation.querySelector(
".p-side-navigation__toggle--in-drawer"
);
if (sideNavigation) {
if (show) {
sideNavigation.classList.remove("is-drawer-collapsed");
sideNavigation.classList.add("is-drawer-expanded");
toggleButtonInsideDrawer.focus();
toggleButtonOutsideDrawer.setAttribute("aria-expanded", true);
toggleButtonInsideDrawer.setAttribute("aria-expanded", true);
} else {
sideNavigation.classList.remove("is-drawer-expanded");
sideNavigation.classList.add("is-drawer-collapsed");
toggleButtonOutsideDrawer.focus();
toggleButtonOutsideDrawer.setAttribute("aria-expanded", false);
toggleButtonInsideDrawer.setAttribute("aria-expanded", false);
}
}
}
// throttle util (for window resize event)
var throttle = function (fn, delay) {
var timer = null;
return function () {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
};
/**
Attaches event listeners for the side navigation toggles
@param {HTMLElement} sideNavigation The side navigation element.
*/
function setupSideNavigation(sideNavigation) {
var toggles = [].slice.call(
sideNavigation.querySelectorAll(".js-drawer-toggle")
);
var drawerEl = sideNavigation.querySelector(".p-side-navigation__drawer");
// hide navigation drawer on small screens
sideNavigation.classList.add("is-drawer-hidden");
// setup drawer element
drawerEl.addEventListener("animationend", () => {
if (!sideNavigation.classList.contains("is-drawer-expanded")) {
sideNavigation.classList.add("is-drawer-hidden");
}
});
window.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
toggleDrawer(sideNavigation, false);
}
});
// setup toggle buttons
toggles.forEach(function (toggle) {
toggle.addEventListener("click", function (event) {
event.preventDefault();
if (sideNavigation) {
sideNavigation.classList.remove("is-drawer-hidden");
toggleDrawer(
sideNavigation,
!sideNavigation.classList.contains("is-drawer-expanded")
);
}
});
});
// hide side navigation drawer when screen is resized
window.addEventListener(
"resize",
throttle(function () {
toggles.forEach((toggle) => {
return toggle.setAttribute("aria-expanded", false);
});
// remove expanded/collapsed class names to avoid unexpected animations
sideNavigation.classList.remove("is-drawer-expanded");
sideNavigation.classList.remove("is-drawer-collapsed");
sideNavigation.classList.add("is-drawer-hidden");
}, 10)
);
}
/**
Attaches event listeners for all the side navigations in the document.
@param {String} sideNavigationSelector The CSS selector matching side navigation elements.
*/
function setupSideNavigations(sideNavigationSelector) {
// Setup all side navigations on the page.
var sideNavigations = [].slice.call(
document.querySelectorAll(sideNavigationSelector)
);
sideNavigations.forEach(setupSideNavigation);
}
setupSideNavigations('.p-side-navigation, [class*="p-side-navigation--"]');
// Setup expandable side navigation
var expandToggles = document.querySelectorAll(".p-side-navigation__expand");
var navigationLinks = document.querySelectorAll(".p-side-navigation__link");
// setup default values of aria-expanded for the toggle button, list title and list itself
const setup = (toggle) => {
const isExpanded = toggle.getAttribute("aria-expanded") === "true";
if (!isExpanded) {
toggle.setAttribute("aria-expanded", isExpanded);
}
const item = toggle.closest(".p-side-navigation__item");
const link = item.querySelector(".p-side-navigation__link");
const nestedList = item.querySelector(".p-side-navigation__list");
if (!link?.hasAttribute("aria-expanded")) {
link.setAttribute("aria-expanded", isExpanded);
}
if (!nestedList?.hasAttribute("aria-expanded")) {
nestedList.setAttribute("aria-expanded", isExpanded);
}
};
const handleToggle = (e) => {
const item = e.currentTarget.closest(".p-side-navigation__item");
const button = item.querySelector(".p-side-navigation__expand");
const link = item.querySelector(".p-side-navigation__link");
const nestedList = item.querySelector(".p-side-navigation__list");
[button, link, nestedList].forEach((el) =>
el.setAttribute(
"aria-expanded",
el.getAttribute("aria-expanded") === "true" ? "false" : "true"
)
);
};
expandToggles.forEach((toggle) => {
setup(toggle);
toggle.addEventListener("click", (e) => {
handleToggle(e);
});
});
});
</script>
<script src="/static/js/modules/discourse-rad-parser/discourse-rad-parser.js"></script>
<script>
drpNs.DiscourseRADParser();
</script>
{% endblock js_extra %}
{% endblock body %}

View File

@ -0,0 +1,10 @@
{% with
document=document,
nav_items=nav_items,
search_action="/maas/docs/search",
siteSearch="/maas/docs",
placeholder="Search MAAS docs",
navigation=navigation
%}
{% include "docs/shared/_docs.html" %}
{% endwith %}

View File

@ -0,0 +1,12 @@
{% with
title="MAAS Docs",
query=query,
results=results,
search_action="/maas/docs/search",
siteSearch="/maas/docs",
placeholder="Search maas Docs",
search_path="/maas/docs/search",
forum_link="https://discourse.maas.io/"
%}
{% include "docs/shared/_search-results.html" %}
{% endwith %}

View File

@ -0,0 +1,195 @@
{% extends "base_index.html" %}
{% block title %}How it works{% endblock %}
{% block meta_copydoc %}
https://docs.google.com/document/d/16tkFyk2W-AkoJYeE9qoFjwzHBlH4diazN9tlqRsV3XA/edit
{% endblock meta_copydoc %}
{% block content %}
<section class="p-strip--image is-dark p-takeover--no-overlays">
<div class="row u-equal-height u-vertically-center">
<div class="col-6">
<h1>How it works</h1>
<p>
MAAS has a tiered architecture with a central postgres database backing a &lsquo;Region Controller (regiond)&rsquo; that deals with operator requests. Distributed Rack Controllers (rackd) provide high-bandwidth services to multiple racks. The controller itself is stateless and horizontally scalable, presenting only a REST API.
</p>
<p>
Rack Controller (rackd) provides <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>, <abbr title="Intelligent Platform Management Interface">IPMI</abbr>, <abbr title="Preboot Execution Environment">PXE</abbr>, <abbr title="Trivial File Transfer Protocol">TFTP</abbr> and other local services. They cache large items like operating system install images at the rack level for performance but maintain no exclusive state other than credentials to talk to the controller.
</p>
</div>
<div class="col-6 u-align--center">
<img src="https://assets.ubuntu.com/v1/b03d95a1-maas.io-how-it-works.svg"
alt="MAAS structure diagram" />
</div>
</div>
</section>
<section class="p-strip is-deep u-no-padding--bottom" id="high-availability">
<div class="row">
<div class="col-8">
<h2>High availability in MAAS</h2>
<p>
MAAS is a mission critical service, providing infrastructure coordination upon which HPC and cloud infrastructures depend. High availability in the region controller is achieved at the database level. The region controller will automatically switch gateways to ensure high availability of services to network segments in the event of a rackd failure.
</p>
</div>
</div>
</section>
<section class="p-strip is-shallow u-hidden--small">
<div class="row">
<div class="col-12">
{{ image(url="https://assets.ubuntu.com/v1/d788fae0-maas.io-high-availability.svg",
alt="High availability network diagram",
width="964",
height="342",
hi_def=True,
attrs={"class": "u-no-margin--bottom"},) | safe
}}
</div>
</div>
</section>
<section class="p-strip is-deep u-no-padding--top">
<div class="row">
<div class="col-8">
<p>
Rackds are not in the primary data path, they are not routers or otherwise involved in the flow of data traffic, this diagram shows only the role that MAAS Rackds play in providing local services to racks, and the way in which they can cover for one another in the event of a failure.
</p>
<p>
MAAS can scale from a small set of servers to many racks of hardware in a datacentre. High-bandwidth activities (such as the initial operating system installation) are handled by the distributed gateways enabling massively parallel deployments.
</p>
</div>
</div>
</section>
<section class="p-strip--accent is-deep" id="protocols">
<div class="row u-equal-height">
<div class="col-8">
<h2>Protocols</h2>
<p>
MAAS uses standard server <abbr title="Baseboard Management Controller">BMC</abbr> and <abbr title="Network Interface Controller">NIC</abbr> services such as <abbr>IPMI</abbr> and PXE to control the machines in your data centre. For converged infrastructure, MAAS talks to the chassis controller of the rack or hyperscale chassis such as Intel RSD, Cisco UCS or HP Moonshot. Custom plugins extend MAAS for alternative BMC protocols.
</p>
<p>
Initial machine inventory and commissioning is done from an ephemeral Ubuntu image that works across all major servers from all major vendors. It is possible to add custom scripts for firmware updates and reporting.
</p>
</div>
<div class="prefix-1 col-4 u-vertically-center">
{{ image(url="https://assets.ubuntu.com/v1/1e561874-maas.io-protocols.svg",
alt="",
width="238",
height="238",
hi_def=True,
attrs={"class": "u-hidden--small"}) | safe
}}
</div>
</div>
</section>
<section class="p-strip is-deep u-no-padding--bottom"
id="physical-availability-zones">
<div class="row">
<div class="col-8">
<h2>Physical availability zones</h2>
<p>
In keeping with the notion of a &lsquo;physical cloud&rsquo; MAAS lets you designate machines as belonging to a particular availability zone. It is typical to group sets of machines by rack or room or building into an availability zone based on common points of failure. The natural boundaries of a zone depend largely on the scale of deployment and the design of physical interconnects in the data centre.
</p>
<p>
Nevertheless the effect is to be able to a scale-out service across multiple failure domains very easily, just as you would expect on a public cloud. Higher-level infrastructure offerings like OpenStack or Mesos can present that information to their API clients as well, enabling very straightforward deployment of sophisticated solutions from metal to container.
</p>
</div>
</div>
</section>
<section class="p-strip u-hidden--small">
<div class="row">
<div class="col-12">
{{ image(url="https://assets.ubuntu.com/v1/d1dc00ae-maas.io-physical-availability-zones.svg",
alt="Availability zone diagram",
width="573",
height="258",
hi_def=True,
attrs={"class": "u-no-margin--bottom"},) | safe
}}
</div>
</div>
</section>
<section class="p-strip is-bordered is-deep u-no-padding--top">
<div class="row">
<div class="col-8">
<p>
The MAAS API allows for discovery of the zones in the region. Chef, Puppet, Ansible and Juju can transparently spread services across the available zones.
</p>
<p>Users can also specifically request machines in particular AZs.</p>
<p>
There is no forced correlation between a machine location in a particular rack and the zone in which MAAS will present it, nor is there a forced correlation between network segment and rack. In larger deployments it is common for traffic to be routed between zones, in smaller deployments the switches are often trunked allowing subnets to span zones.
</p>
<p>
By convention, users are entitled to assume that all zones in a region are connected with very high bandwidth that is not metered, enabling them to use all zones equally and spread deployments across as many zones as they choose for availability purposes.
</p>
</div>
</div>
</section>
<section class="p-strip is-deep" id="node-lifecycle">
<div class="row">
<div class="col-8">
<h2>The node lifecycle</h2>
<p>
Each machine (&ldquo;node&rdquo;) managed by MAAS goes through a lifecycle &mdash; from its enlistment or onboarding to MAAS, through commissioning when we inventory and can setup firmware or other hardware-specific elements, then allocation to a user and deployment, and finally they are released back to the pool or retired altogether.
</p>
</div>
</div>
<br />
<div class="row u-equal-height">
<div class="col-5 u-hidden--medium u-hidden--small u-vertically-center">
{{ image(url="https://assets.ubuntu.com/v1/b2cec06d-maas.io-node-lifecycle.svg",
alt="Node lifecycle chart",
width="353",
height="662",
hi_def=True,) | safe
}}
</div>
<div class="col-7">
<h3 class="p-heading--4">New</h3>
<p>
New machines which PXE-boot on a MAAS network will be enlisted automatically if MAAS can detect their BMC parameters. The easiest way to enlist standard <abbr>IPMI</abbr> servers is simply to PXE-boot them on the MAAS network.
</p>
<h3 class="p-heading--4">Commissioning</h3>
<p>
Detailed inventory of RAM, CPU, disks, NICs and accelerators like GPUs itemized and usable as constraints for machine selection. It is possible to run your own scripts for site-specific tasks such as firmware updates.
</p>
<h3 class="p-heading--4">Ready</h3>
<p>
A machine that is successfully commissioned is considered &ldquo;Ready&rdquo;. It will have configured BMC credentials (on IPMI based BMCs) for ongoing power control, ensuring that MAAS can start or stop the machine and allocate or (re)deploy it with a fresh operating system.
</p>
<h3 class="p-heading--4">Allocated</h3>
<p>
Ready machines can be allocated to users, who can configure network interface bonding and addressing, and disks, such as LVM, RAID, bcache or partitioning.
</p>
<h3 class="p-heading--4">Deploying</h3>
<p>
Users then can ask MAAS to turn the machine on and install a complete server operating system from scratch without any manual intervention, configuring network interfaces, disk partitions and more.
</p>
<h3 class="p-heading--4">Releasing</h3>
<p>
When a user has finished with the machine, they can release it back to the shared pool of capacity. You can ask MAAS to ensure that there is a full disk-wipe of the machine when that happens.
</p>
</div>
</div>
</section>
<section class="p-strip--accent is-shallow">
<div class="row u-equal-height">
<div class="col-10 u-sv3--small">
<h3 class="p-heading--4 u-no-margin--bottom">
MAAS is a bare-metal server provisioning tool. It is open source and&nbsp;free.
</h3>
<br class="u-hide--medium u-hide--large" />
</div>
<div class="col-2 u-vertically-center">
<a aria-label="Find out how to install MAAS"
href="/maas/docs/how-to-get-maas-up-and-running"
class="p-button--positive u-no-margin--bottom">Install MAAS</a>
</div>
</div>
</section>
{% endblock %}

1060
templates/maas/index.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,564 @@
{% extends "base_index.html" %}
{% block title %}Understand MAAS:Resources{% endblock %}
{% block meta_description %}
A collection of useful and educational links to articles and information about
MAAS (Metal as a Service). Learn more about bare metal clouds from some of the
industrys best.
{% endblock %}
{% block meta_copydoc %}
https://docs.google.com/document/d/1OXio660sPmWUllHW0CO8Dl24p6E6Jasl7be8szP6z-k/edit
{% endblock meta_copydoc %}
{% block content %}
<section class="p-strip--image is-dark p-takeover--no-overlays">
<div class="row u-equal-height u-vertically-center">
<div class="col-4">
<span>MAAS 3.1</span>
<h1>Understand MAAS: Resources</h1>
</div>
<div class="col-8">
<div class="row">
<div class="col-6 col-start-large-2">
<p>
Explore a collection of useful resources that help you understand
and evaluate MAAS when building your bare metal cloud.
</p>
<p>
Whitepapers, blogs, customer presentations, webinars, and more are
conveniently collected here. Well guide you through what each
resource is about, and add more to this page over time.
</p>
</div>
</div>
</div>
</div>
</section>
<section class="p-strip u-no-padding--bottom">
<div class="u-fixed-width">
<h2>
Customers <3 MAAS
</h2>
</div>
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 id="building-the-datacenter" class="p-heading--4">Building the datacenter</h3>
<p class="p-heading--5">Implementing self-service for large-scale operations - T-Mobile</p>
<p>
In this talk by Joshua McClintock, MTS, Systems Design Engineering,
T-Mobile, youll hear about how he built a self-service portal using
MAAS to allow people to order servers like burgers.
</p>
<p>
One of the best talks to understand one of the greatest benefits of
MAAS - faster time-to-delivery.
</p>
<a aria-describedby="building-the-datacenter"
href="https://youtu.be/dSZqax12Q7A">Watch the presentation</a>
</div>
<div class="col-8">
<div class="u-embedded-media u-hide--small">
<iframe width="560"
height="302"
src="https://www.youtube.com/embed/dSZqax12Q7A?controls=0"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
</div>
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 id="how-roblox">
How Roblox went from Windows to Ubuntu in seven days for edge compute
nodes
</h3>
<p>
Roblox is a gaming platform for 100 million kids all over the world,
and to serve them must deploy edge compute globally for low latency
gaming experiences. This means imaging, managing and rebuilding
thousands of servers.
</p>
<p>
In this talk, Rob Cameron, Roblox Technical Director for Cloud
Services, shares how they migrated servers from Windows to Linux for
approximately 200K containerised workloads in a seven-day timeframe,
leveraging MAAS for the path to full orchestration. This is another
example of MAAS enabling faster time-to-delivery.
</p>
<a aria-describedby="how-roblox" href="https://youtu.be/SwlU4U-BWRo">Watch the presentation</a>
</div>
<div class="col-8">
<div class="u-embedded-media u-hide--small">
<iframe width="560"
height="302"
src="https://www.youtube.com/embed/SwlU4U-BWRo?controls=0"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
</div>
</div>
</div>
</article>
</section>
<section class="p-strip u-no-padding--bottom">
<div class="row">
<hr />
<div class="col-12">
<h2>Must reads</h2>
</div>
</div>
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">
<a href="https://ubuntu.com/engage/bare-metal-kubernetes">Easy and automated bare metal Kubernetes: The definitive whitepaper</a>
</h3>
</div>
<div class="col-4">
<p>Read the definitive whitepaper on bare metal Kubernetes featuring MAAS.</p>
<p>
This whitepaper goes in depth into the history of VMs, how they compare with Kubernetes, and the important role bare metal orchestration (and MAAS) has to play.
Learn how to deploy Kubernetes on bare metal with MAAS, and the benefits that it has.
Designed to go hand in hand with the bare metal K8s video tutorial.
</p>
</div>
<div class="col-4 u-align--center">
<img src="https://assets.ubuntu.com/v1/a9954c8e-hp-moonshot-server.jpg"
alt=""
width="300"
height="237" />
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<div class="row">
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">
<a href="https://ubuntu.com/engage/epa-for-open-ran-infrastructure">Turbo charge your bare metal cloud with MAAS</a>
</h3>
</div>
<div class="col-4">
<p>
When deploying a bare metal cloud, its critical to maximise your capital investment.
Workloads need to be correctly deployed to the right machines with the right capabilities,
at the right time.
</p>
<p>
Read this whitepaper to learn more about how MAAS helps turbo charge your hardware with EPA
(Enhanced Platform Awareness). Includes a practical example of auto-labelling and configuring
machines with GPUs.
</p>
</div>
<div class="col-4 u-align--center">
<img alt=""
loading="lazy"
src="https://assets.ubuntu.com/v1/53e154b5-maas+turbo+charge+hw.png"
srcset="https://assets.ubuntu.com/v1/53e154b5-maas+turbo+charge+hw.png"
width="747"
height="383" />
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">
<a href="https://ubuntu.com/blog/bare-metal-kubernetes-clusters-spectro-cloud-maas">Provisioning Bare Metal Kubernetes Clusters</a>
</h3>
</div>
<div class="col-4">
<p>
In this blog post, we discuss how Bare Metal Kubernetes was enabled
by SpectroCloud, who built a ClusterAPI Provider for MAAS using the
MAAS API.
</p>
<p>
A textbook example of how MAAS is designed to be used to enable
automated bare metal provisioning.
</p>
</div>
<div class="col-4 u-align--center">
<img alt=""
loading="lazy"
src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,c_fill,w_207,h_251/https://lh3.googleusercontent.com/INmNUbiacgh9pSDKku0nh0XXtC9mlGIndW060gc-RLHrb23ZBBwvHXiJH-_S6V70sYbuLcsxOamr0cjjmVPScMKeahyVeuXIoqa8jp2c-dM-5IXs-tYO_wr9USVxjnvaWQb68XG-=s0"
srcset="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,c_fill,w_414,h_502/https://lh3.googleusercontent.com/INmNUbiacgh9pSDKku0nh0XXtC9mlGIndW060gc-RLHrb23ZBBwvHXiJH-_S6V70sYbuLcsxOamr0cjjmVPScMKeahyVeuXIoqa8jp2c-dM-5IXs-tYO_wr9USVxjnvaWQb68XG-=s0 2x"
width="207"
height="251" />
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">
<a href="https://pages.ubuntu.com/eBook-MAAS.html">
Server provisioning: What Network Admins and IT Pros need to know
</a>
</h3>
</div>
<div class="col-4">
<p>
In this whitepaper, learn everything you need to know about the
benefits of bare-metal provisioning, and how leading companies are
using server provisioning solutions within their hyperscale
environments.
</p>
</div>
<div class="col-4 u-align--center">
<img src="https://pages.ubuntu.com/rs/066-EOV-335/images/maas_banners_leaderboard%20%281%29.png"
width="200"
height="200"
alt="" />
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">
<a href="https://ubuntu.com/engage/maas-hardware-testing">MAAS automated testing capabilities</a>
</h3>
</div>
<div class="col-4">
<p>
In this whitepaper, you will learn how MAAS provides a flexible and
straightforward framework for administrators to test their hardware.
Explore the following:
</p>
<ul>
<li>What MAAS frameworks allow users to do</li>
<li>How MAAS installs dependencies, and tracks progress and results</li>
<li>
The types of tests MAAS provides in relation to storage, CPU,
memory and others
</li>
<li>How MAAS tests servers at scale</li>
</ul>
<p>
Automated hardware testing is a key component of bare metal clouds,
particularly at scale.
</p>
</div>
<div class="col-4 u-align--center">
<img alt=""
loading="lazy"
src="https://assets.ubuntu.com/v1/78b0186c-web-interface-rest-api.png" />
</div>
</div>
</article>
</div>
</section>
<section class="p-strip u-no-padding--bottom">
<div class="row">
<hr />
<div class="col-12">
<h2>Blogs</h2>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
<a href="https://ubuntu.com/blog/topics/maas">All Canonical blogs related to MAAS are here.</a>
This rich set of content covers everything from high-level product
announcements to hands-on technical guides that dig into more
complicated topics.
</p>
</div>
</div>
<div id="latest-articles" class="row">
<div style="min-height: 9.1rem">
<i class="p-icon--spinner u-animation--spin">Loading...</i>
</div>
</div>
<template style="display:none" id="articles-template">
<article class="col-4 col-medium-3 p-blog-card--maas">
<div class="p-card__content">
<div class="u-sv1">
<div class="article-image p-image-container--16-9" aria-hidden="true"></div>
<h3 class="p-heading--4">
<a class="p-link--soft article-title article-link"></a>
</h3>
<p>
<em class="article-time"></em>
</p>
</div>
</div>
</article>
</template>
<script src="{{ versioned_static('js/modules/latest-news/latest-news.js') }}"></script>
<script>
canonicalLatestNews.fetchLatestNews({
articlesContainerSelector: "#latest-articles",
articleTemplateSelector: "#articles-template",
limit: "3",
gtmEventLabel: "maas resources",
tagId: 1304 // MAAS tag ID
})
</script>
</section>
<section class="p-strip u-no-padding--bottom">
<div class="row">
<hr />
<div class="col-12">
<h2>Expert classes</h2>
</div>
</div>
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">Exploring MAAS with LXD</h3>
</div>
<div class="col-4">
<p>
Stéphane Graber, Engineering Manager for LXD,
<a href="https://www.youtube.com/watch?v=b_bdVfG47G4">shows us how to install MAAS inside a LXD container</a>
and see how it can be used to deploy LXD virtual machines, provide DNS
and IP management for LXD instances and more!
</p>
<p>
This is an excellent video for those that want to understand more
about LXD and MAAS.
</p>
</div>
<div class="col-4">
<div class="u-embedded-media">
<iframe width="560"
height="302"
src="https://www.youtube.com/embed/b_bdVfG47G4?controls=0"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
</div>
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">Bare metal Kubernetes hands on tutorial</h3>
</div>
<div class="col-4">
<p>
Anton Smith, Product Manager for MAAS takes you hands-on to
<a href="https://www.youtube.com/watch?v=sLADei_c9Qg">build your own simulated bare metal Kubernetes cluster</a>
using just a single computer.
</p>
<p>
Along the way, youll get to use and learn about some Linux
networking, MAAS, LXD, Ceph, Juju and Kubernetes, and at the end
deploy an application to your new K8s cluster.
</p>
<p>
This video is great for understanding the different possibilities
enabled by MAAS, Juju, and Charms.
</p>
</div>
<div class="col-4">
<div class="u-embedded-media">
<iframe width="560"
height="302"
src="https://www.youtube.com/embed/sLADei_c9Qg?controls=0"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
</div>
</div>
</div>
</article>
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">
<a href="https://ubuntu.com/engage/introduction-to-bare-metal-cloud">Introduction to bare metal cloud</a>
</h3>
</div>
<div class="col-4">
<p>
Alex Chalkias and Anton Smith (product managers for K8s and MAAS respectively) discuss and
present bare metal K8s, and provide an overview to go with the hands on tutorial above.
</p>
<p>
With plenty of really interesting questions by the audience, this is a great primer for people
wanting to further their understanding of bare metal cloud and kubernetes.
</p>
</div>
<div class="col-4 u-align--center">
<img alt=""
loading="lazy"
src="https://assets.ubuntu.com/v1/11946b18-juju+maas+k8s.png"
srcset="https://assets.ubuntu.com/v1/11946b18-juju+maas+k8s.png"
width="921"
height="532" />
</div>
</div>
</article>
</section>
<section class="p-strip is-bordered">
<div class="row">
<hr />
<div class="col-12">
<h2>Community</h2>
</div>
</div>
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">MAASberry Pi</h3>
</div>
<div class="col-4">
<p>
Do you love Raspberry Pis and Ubuntu as much as we do?
Now you can install Ubuntu for ARM using MAAS on RPI4s.
</p>
<p>
Build your own mini bare metal cloud by
<a href="/maas/tutorials/build-your-own-bare-metal-cloud-using-a-raspberry-pi-cluster-with-maas#1-overview">
following this tutorial
</a> which resulted from a great collaboration with the MAAS community.
</p>
</div>
<div class="col-4 u-align--center">
<img alt=""
loading="lazy"
src="https://assets.ubuntu.com/v1/60376789-rpi+cluster.png"
srcset="https://assets.ubuntu.com/v1/60376789-rpi+cluster.png"
width="1375"
height="1322" />
</div>
</div>
</article>
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">Using the MAAS CLI</h3>
</div>
<div class="col-4">
<p>
Follow Stormrider as he uses the CLI to get MAAS setup and perform various machine
related tasks. This is a good example of step-by-step usage of the CLI
and a great way to learn.
</p>
</div>
<div class="col-4">
<div class="u-embedded-media">
<a href="https://stormrider.io/maas-cli-1.html"
aria-label="Using the MAAS CLI">
<img src="https://assets.ubuntu.com/v1/f33bcbd3-maas-setup-cli.png" alt="" />
</a>
</div>
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">Bare metal Kubernetes hands on tutorial</h3>
</div>
<div class="col-4">
<p>
In this
<a href="https://www.spectrocloud.com/webinars/managing-bare-metal-k8s-like-any-other-cluster/">webinar</a>, you will learn about how to overcome the challenge of running
Kubernetes directly on bare metal servers and benefit from performance
and cost efficiencies, without having to treat those environments as
“special projects”. Combining CNCFs Cluster API and Canonicals
Metal-as-a-Service (MaaS), Saad and Joep will introduce an
architecture that will enable any team to deploy and treat bare metal
Kubernetes clusters just like any other cluster in their container
environment.
</p>
</div>
<div class="col-4">
<div class="u-embedded-media">
<a href="https://www.spectrocloud.com/webinars/managing-bare-metal-k8s-like-any-other-cluster/"
aria-label="Managing Bare Metal K8s webinar">
<img src="https://assets.ubuntu.com/v1/5170cdb7-bare-metal-webinar.png"
alt="" />
</a>
</div>
</div>
</div>
</article>
<hr class="is-muted is-fixed-width" />
<article class="p-strip is-shallow">
<div class="row">
<div class="col-4">
<h3 class="p-heading--4">Bare metal Kubernetes hands on tutorial</h3>
</div>
<div class="col-4">
<p>
Community member
<a href="https://ssbostan.medium.com/">Saeid Bostandoust</a> has
written a tool called MAASTA, that lets you interact with a MAAS
server cloud using Terraform and Ansible, just the same way as you
would interact with a public cloud.
</p>
<p>
The <a href="https://github.com/ssbostan/maasta">repository</a> is
here, and
<a href="https://itnext.io/maas-terraform-ansible-integration-adb57e09caf2">
an introduction to the project can be found here.
</a>
</p>
</div>
<div class="col-4">
<div class="u-embedded-media">
<a href="https://itnext.io/maas-terraform-ansible-integration-adb57e09caf2"
aria-label="MAAS Terraform Ansible Integration">
<img src="https://assets.ubuntu.com/v1/a34d4bed-maas-terraform.png" alt="" />
</a>
</div>
</div>
</div>
</article>
</section>
{% endblock %}

407
templates/maas/tour.html Normal file
View File

@ -0,0 +1,407 @@
{% extends "base_index.html" %}
{% block title %}Tour{% endblock %}
{% block meta_copydoc %}https://docs.google.com/document/d/1KcYwNK0pJyiDVEDq4vTpv6BX_rpSDnxUxtAvAnsRKyw/edit{% endblock meta_copydoc %}
{% block content %}
<section class="p-strip--image is-dark p-takeover--no-overlays">
<div class="row">
<h4>MAAS 2.7</h4>
<h1 class="u-no-margin--bottom" itemprop="description">Overview and new features<br class="u-hide--small u-hide--medium" /> in the latest release</h1>
</div>
</section>
<section class="p-strip is-deep is-bordered" id="micro-clouds">
<div class="row">
<div class="col-12">
<h2>Create custom VMs with KVM Micro-clouds</h2>
</div>
<div class="p-divider">
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a class="u-align--center venobox venobox--expand" href="https://assets.ubuntu.com/v1/952c8938-overview-of-kvms.png" data-gall="tourGallery" title="Create custom VMs with KVM Micro-clouds" aria-label="Modal link to view larger screenshot of create custom VMs with KVM Micro-clouds">
<img class="p-image--bordered" src="https://assets.ubuntu.com/v1/952c8938-overview-of-kvms.png?h=172" alt="Screenshot of create custom VMs with KVM Micro-clouds" height="192">
</a>
</div>
<h3>Graphical overview of your KVM hosts resources</h3>
<p>MAAS shows your KVM pods CPU cores and RAM, as well as the free space in storage pools.</p>
<p class="u-sv2">Manage and visualise overcommit ratios.</p>
<p><a href="/maas/docs/how-to-manage-machines#p-9078-add-lxd-for-vm-hosts"
onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'KVM' });"
aria-label="Link to KVM in MAAS">Learn more about KVM in MAAS&nbsp;&rsaquo;</a>
</p>
</div>
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/28b7223a-choose-storage-from-multiple-pools.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="Choose storage from multiple pools" aria-label="Modal link to view larger screenshot of Choose storage from multiple pools">
<img src="https://assets.ubuntu.com/v1/28b7223a-choose-storage-from-multiple-pools.png?h=172" class="p-image--bordered" height="192" alt="Screenshot of the subnets listing">
</a>
</div>
<h3>Choose storage from multiple pools</h3>
<p>Assign one or more volumes from the default and other available pools. </p>
<p>View the total size of your requests and the free space remaining.</p>
</div>
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/7af5b0bc-customise-a-VMs-network-interfaces.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="Customise a VMs network interfaces" aria-label="Modal link to view larger screenshot of Customise a VMs network interfaces">
<img src="https://assets.ubuntu.com/v1/7af5b0bc-customise-a-VMs-network-interfaces.png?h=172" class="p-image--bordered" alt="Screenshot of Customise a VMs network interfaces">
</a>
</div>
<h3>Customise a VMs network interfaces</h3>
<p>Create software defined networking as complex as you need.</p>
<p>Assign interfaces to spaces for Juju models, browse subnets by fabric and VLAN, or simply type an IP number.</p>
</div>
</div>
</div>
</section>
<section class="p-strip--light is-deep is-bordered" id="automation">
<div class="row">
<div class="col-12">
<h2>Automate your infrastructure setup</h2>
</div>
<div class="p-divider">
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a class="u-align--center venobox venobox--expand" href="https://assets.ubuntu.com/v1/4c793634-Unattended+server+discovery.png" data-gall="tourGallery" title="MAAS node listing page" aria-label="Modal link to view larger screenshot of the node listing">
<img src="https://assets.ubuntu.com/v1/4c793634-Unattended+server+discovery.png?w=360" alt="Screenshot of node listing" class="p-image--bordered" />
</a>
</div>
<h3>Unattended server discovery</h3>
<p><abbr title="Preboot eXecution Environment">PXE</abbr> boot your servers and containers and they will be automatically discovered and enlisted in MAAS.</p>
<p class="u-sv2"><abbr title="Intelligent Platform Management Interface">IPMI</abbr> enabled machines work seamlessly with MAAS.</p>
<p><a href="/maas/docs/how-to-manage-machines"
onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Automation' });"
aria-label="Link to adding nodes page on MAAS documentation">Learn more about adding new nodes to MAAS&nbsp;&rsaquo;</a>
</p>
</div>
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/69efb7c8-Effortless+network+discovery.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="MAAS subnets listing page" aria-label="Modal link to view larger screenshot of subnets listing">
<img src="https://assets.ubuntu.com/v1/69efb7c8-Effortless+network+discovery.png?w=360" alt="Screenshot of the subnets listing" class="p-image--bordered" />
</a>
</div>
<h3>Effortless network discovery</h3>
<p>MAAS will automatically discover your network, including:</p>
<ul>
<li>Subnets</li>
<li>Accessible <abbr title="Virtual Local Area Network">VLAN</abbr>s</li>
<li>Attached switch fabrics</li>
</ul>
<p><a href="/maas/docs/about-maas-networking"
onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });"
aria-label="Link to the configuring networking page on MAAS documentation">Find out more about MAAS networking&nbsp;&rsaquo;</a>
</p>
</div>
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/5abc8215-Simple+device+discovery.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="MAAS device discovery page" aria-label="Modal link to view larger screenshot of Device discovery">
<img src="https://assets.ubuntu.com/v1/5abc8215-Simple+device+discovery.png?w=360" alt="Screenshot of device discovery" class="p-image--bordered" />
</a>
</div>
<h3>Simple device discovery</h3>
<p>MAAS can discover new <a href="/maas/docs/about-maas-networking" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Interested in feature', 'eventAction' : 'Click', 'eventLabel' : 'Learn more about interfaces' });" aria-label="Link to device discovery page on MAAS documentation">devices and network interfaces&nbsp;&rsaquo;</a>:</p>
<ul>
<li>Passively</li>
<li>On-demand</li>
<li>Periodically</li>
</ul>
<p>
<a href="/maas/docs/about-maas-networking"
onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Automation' });
dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Interested in feature', 'eventAction' : 'Click', 'eventLabel' : 'Learn more about device discovery and subnet mapping' });"
aria-label="Link to the configuring networking page on MAAS documentation">Learn more about device discovery and subnet mapping&nbsp;&rsaquo;</a>
</p>
</div>
</div>
</div>
</section>
<section class="p-strip is-deep is-bordered" id="fast-deployment">
<div class="row">
<div class="col-8">
<h2>Manage your servers without leaving<br class="u-hide--small u-hide--medium" /> your seat</h2>
<p class="u-sv2">Use the Web <abbr title="User interface">UI</abbr> or the command line (<abbr title="Command-line interface">CLI</abbr>) to remotely manage your nodes or use the <abbr title="Application programming interface">API</abbr> to automate management.</p>
</div>
</div>
<div class="row">
<div class="p-divider">
<div class="col-6 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/8156f5fa-operate-your-machines-remotely.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="Node listing actions" aria-label="Modal link to view larger screenshot of node listing actions">
<img src="https://assets.ubuntu.com/v1/8156f5fa-operate-your-machines-remotely.png?h=295" alt="Screenshot of node listing actions" class="p-image--bordered" />
</a>
</div>
<h3>Operate your machines remotely</h3>
<p>Manage individual or groups of servers.</p>
<ul>
<li>Power on/off</li>
<li>Commission</li>
<li>Deploy</li>
<li>Assign an owner</li>
<li>Mark a node fixed or broken</li>
<li>Enter rescue mode </li>
<li>Test your hardware</li>
<li>Assign to physical zones</li>
</ul>
<p>
<a href="/maas/docs/about-machine-basics#heading--machine-life-cycle"
onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Fast deployment' });"
aria-label="Link to machine lifecycle page on MAAS documentation">Learn more about the node actions&nbsp;&rsaquo;</a>
</p>
</div>
<div class="col-6 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/9c1e1198-Provision+with+any+OS+image.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="Operating system image page" aria-label="Modal link to view larger screenshot of the operating system image page">
<img src="https://assets.ubuntu.com/v1/9c1e1198-Provision+with+any+OS+image.png?h=250" alt="Screenshot of the operating system image page" class="p-image--bordered" />
</a>
</div>
<h3>Provision with any <abbr title="Operating system">OS</abbr> image</h3>
<p>Select the OS you require in your data centre <span aria-describedby="image-info">*</span></p>
<ul>
<li>Ubuntu</li>
<li>CentOS</li>
<li>Windows</li>
<li>RHEL</li>
</ul>
<p>Import, update or sync the images or connect to an onsite mirror to work offline.</p>
<p id="image-info"><small>* Images other than Ubuntu and CentOS require an <a href="https://www.ubuntu.com/pro" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Interested in Professional', 'eventAction' : 'Click', 'eventLabel' : 'Contact Us' });" aria-label="External link to the Ubuntu Pro page on ubuntu dot com">Ubuntu Pro</a> licence</small> </p>
<p class="u-sv2"><a href="/maas/docs/about-images" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Learn more about images' });" aria-label="Link to the install config images page on MAAS documentation">Learn more about images&nbsp;&rsaquo;</a></p>
</div>
</div>
</div>
<div class="row">
<div class="p-divider">
<div class="col-6 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/e54c8550-deploy-with-the-press-of-a-button.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="Node deployment" aria-label="Modal link to view larger screenshot of node deployment">
<img src="https://assets.ubuntu.com/v1/e54c8550-deploy-with-the-press-of-a-button.png?h=295" alt="Screenshot of node deployment" class="p-image--bordered" />
</a>
</div>
<h3>Deploy with the press of a button</h3>
<ol>
<li>Select the machine</li>
<li>Choose the OS and architecture</li>
<li>Press 'deploy'</li>
</ol>
<p><a href="/maas/docs/how-to-manage-machines#p-9078-deploy-machines" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Fast deployment' });" aria-label="Link to the install and config page of node deployment on MAAS documentation">Learn more about deployment&nbsp;&rsaquo;</a></p>
</div>
<div class="col-6 p-divider__block">
<div class="u-sv2">
<a href="https://assets.ubuntu.com/v1/7c5f27f7-get-all-the-information-you-need.png" class="u-align--center venobox venobox--expand" data-gall="tourGallery" title="Commissioning list" aria-label="Modal link to view larger screenshot of node deployment">
<img src="https://assets.ubuntu.com/v1/7c5f27f7-get-all-the-information-you-need.png?h=293" alt="Screenshot of commissioning list" class="p-image--bordered" />
</a>
</div>
<h3>Get all the information you need</h3>
<ul>
<li>Dig into your hardware details that MAAS gathers during commissioning including; processors, memory, storage, networking, and other components.</li>
<li>Event tracking allows you to monitor your machine throughout its&rsquo; lifecycle.</li>
</ul>
</div>
</div>
</div>
</section>
<section class="p-strip--light is-bordered is-deep" id="hardware-testing">
<div class="row">
<div class="col-12">
<h2>Keep an eye on your hardware</h2>
<p class="u-sv2">Run MAAS provided tests or upload your own.</p>
</div>
<div class="p-divider">
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a class="u-align--center venobox venobox--expand" href="https://assets.ubuntu.com/v1/9d059ff4-check-your-data-centre-health.png" data-gall="tourGallery" title="MAAS node listing page" aria-label="Modal link to view larger screenshot of the node listing">
<img src="https://assets.ubuntu.com/v1/9d059ff4-check-your-data-centre-health.png?h=225" alt="Screenshot of node listing" class="p-image--bordered" />
</a>
</div>
<p>Check your data centre health at a glance and easily identify faulty components.</p>
</div>
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a class="u-align--center venobox venobox--expand" href="https://assets.ubuntu.com/v1/b39748ba-Keep+an+eye+on+your+hardware+-+Machine+details+page.png" data-gall="tourGallery" title="MAAS machine details page" aria-label="Modal link to view larger screenshot of the machine details">
<img src="https://assets.ubuntu.com/v1/b39748ba-Keep+an+eye+on+your+hardware+-+Machine+details+page.png?h=225" alt="Screenshot of machine details" class="p-image--bordered" />
</a>
</div>
<p>Run tests for each component to get up to date information about their health.</p>
<p>Review captured metrics to better understand your hardwares performance.</p>
</div>
<div class="col-4 p-divider__block">
<div class="u-sv2">
<a class="u-align--center venobox venobox--expand" href="https://assets.ubuntu.com/v1/5040a772-Access+all+historical+testing+data.png" data-gall="tourGallery" title="MAAS machine hardware tests" aria-label="Modal link to view larger screenshot of the machine hardware tests">
<img src="https://assets.ubuntu.com/v1/5040a772-Access+all+historical+testing+data.png?h=225" alt="Screenshot of machine hardware tests" class="p-image--bordered" />
</a>
</div>
<p>Access all historical testing data to discover trends of component metrics and failures.</p>
</div>
</div>
<p><a href="/maas/docs/how-to-manage-machines#p-9078-deploy-machines" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Machine configuration' });dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Keep an eye on your hardware feature', 'eventAction' : 'Click', 'eventLabel' : 'Learn more about hardware testing' });" aria-label="Link to hardware testing on MAAS documentation">Learn more about hardware testing&nbsp;&rsaquo;</a></p>
</div>
</section>
<section class="p-strip is-deep" id="configure-servers">
<div class="row">
<div class="col-12">
<h2>Configure your servers with a few clicks</h2>
</div>
</div>
<div class="row">
<div class="col-12">
<h3>Easily manage your network interfaces</h3>
</div>
</div>
<div class="row">
<div class="col-6">
<a href="https://assets.ubuntu.com/v1/38217a40-easily-manage-your-network-interfaces.png" class="venobox venobox--expand" data-gall="tourGallery" title="Node details network management" aria-label="Modal link to larger screenshot of node details network management">
<img src="https://assets.ubuntu.com/v1/38217a40-easily-manage-your-network-interfaces.png?w=485" alt="Screenshot of node details network management" class="p-image--bordered" />
</a>
</div>
<div class="col-6">
<p>Set up your Ethernet interfaces easily, and get your nodes ready to work as soon as they&apos;re deployed. MAAS supports:</p>
<ul>
<li><abbr title="Internet Protocol">IP</abbr> address assignment</li>
<li>Bonding</li>
<li>VLAN configuration</li>
<li>Virtual bridges</li>
<li>Static routes and more&hellip;</li>
</ul>
<p><a href="/maas/docs/how-to-manage-machines#p-9078-deploy-machines" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Machine configuration' });dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Interested in feature', 'eventAction' : 'Click', 'eventLabel' : 'Learn more about interfaces' });" aria-label="Link to the install config and commission nodes page on MAAS documentation">Learn more about interfaces&nbsp;&rsaquo;</a></p>
</div>
</div>
</section>
<section class="p-strip is-deep is-bordered u-no-padding--top">
<div class="row">
<div class="col-12">
<h3>Configure any storage layout no matter how complex</h3>
</div>
</div>
<div class="row">
<div class="col-6">
<a href="https://assets.ubuntu.com/v1/6f3a12ef-configure-any-storage-layout.png" class="venobox venobox--expand" data-gall="tourGallery" title="Node details storage management" aria-label="Modal link to view larger screenshot of node details storage management">
<img src="https://assets.ubuntu.com/v1/6f3a12ef-configure-any-storage-layout.png?w=485" alt="Screenshot of node details storage management" class="p-image--bordered" />
</a>
</div>
<div class="col-6">
<p>Set up your storage, from simple partitioning to complex storage layouts including:</p>
<ul>
<li><abbr title="Block cache">Bcache</abbr></li>
<li><abbr title="Redundant Array of Independent Disks">RAID</abbr></li>
<li><abbr title="Logical Volume Management">LVM</abbr></li>
</ul>
<p><a href="/maas/docs/about-machine-basics" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Machine configuration' });dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Learn more about storage' });" aria-label="Link to install and configure storage on MAAS documentation">Learn more about storage&nbsp;&rsaquo;</a></p>
</div>
</div>
</section>
<section class="p-strip--light is-deep is-bordered" id="manage-network">
<div class="row">
<div class="col-12">
<h2>Manage your network with MAAS</h2>
<h3><abbr title="IP address management">IPAM</abbr> (IP address management) for operational efficiency</h3>
</div>
</div>
<div class="row u-equal-height">
<div class="col-6">
<h4>With MAAS managing <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>, you can&nbsp;easily</h4>
<ul>
<li>Define <abbr title="Internet Protocol address">IP address</abbr> ranges</li>
<li>Create persistent leases</li>
<li>Boot your machines from the network</li>
<li>Receive <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> requests relayed from remote networks</li>
</ul>
<p><a href="/maas/docs/how-to-manage-networks#p-9070-manage-ip-addresses" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Learn more about DHCP in MAAS' });" class="u-sv2" aria-label="Link to install and configure network dhcp page on MAAS documentation">Learn more about <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> in MAAS&nbsp;&rsaquo;</a></p>
</div>
<div class="col-6">
<h4>With full <abbr title="Domain name system">DNS</abbr> management you can</h4>
<ul>
<li>Create multiple <abbr title="Domain name system">DNS</abbr> domains</li>
<li>Add multiple records per domain</li>
<li>Select the domain for machines and devices</li>
<li>Assign additional names to <abbr title="Internet Protocol">IP</abbr> addresses and more&hellip;</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<h3>And much more</h3>
<p>MAAS can easily manage the most complex network environments, including all your:</p>
</div>
</div>
<div class="row">
<ul class="col-4">
<li><abbr title="Internet Protocol version 4">IPv4</abbr> and <a href="/maas/docs/about-maas-networking" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to install and configure network Internet Protocol version 6 on MAAS documentation"><abbr title="Internet Protocol version 6">IPv6</abbr>&nbsp;&rsaquo;</a></li>
<li><a href="/maas/docs/how-to-manage-networks#p-9070-manage-subnets" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to install and configure network subnet management on MAAS documentation">Subnets&nbsp;&rsaquo;</a></li>
<li><a href="/maas/docs/reference-maas-glossary#heading--vlans" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to intro concepts about virtual local area networks on MAAS documentation"><abbr title="Virtual local area network">VLAN</abbr>&nbsp;&rsaquo;</a></li>
</ul>
<ul class="col-4">
<li><a href="/maas/docs/reference-maas-glossary#heading--fabrics" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to intro concepts about fabrics on MAAS documentation">Fabrics&nbsp;&rsaquo;</a></li>
<li><a href="/maas/docs/reference-maas-glossary#heading--spaces" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to intro concepts about spaces on MAAS documentation">Spaces&nbsp;&rsaquo;</a></li>
<li><a href="/maas/docs/how-to-manage-networks" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to install and configure network ntp on MAAS documentation"><abbr title="Network Time Protocol">NTP</abbr>&nbsp;&rsaquo;</a></li>
</ul>
<ul class="col-4">
<li><a href="/maas/docs/how-to-enhance-maas-security#p-9102-use-tls-termination-maas-33" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to install and configure secure sockets layer on MAAS documentation"><abbr title="Secure sockets layer">SSL</abbr>&nbsp;&rsaquo;</a></li>
<li><a href="/maas/docs/how-to-manage-networks" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to install and configure spanning tree protocol on MAAS documentation"><abbr title="Spanning tree protocol">STP</abbr>&nbsp;&rsaquo;</a></li>
<li><a href="/maas/docs/how-to-manage-networks" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'Network management' });" aria-label="Link to install and configure network proxy on MAAS documentation">Proxy&nbsp;&rsaquo;</a></li>
</ul>
</div>
</section>
<section class="p-strip is-bordered">
<div class="row u-equal-height">
<div class="col-6 p-takeunder is-dark" style="background-color: #333;">
<div class="row u-equal-height">
<div class="col-3 u-vertically-center u-align--center u-hide--small">
{{
image(
url="https://assets.ubuntu.com/v1/4508bba8-maas-cli.svg",
alt="MAAS command line interface icon",
width="150",
height="129",
hi_def=True,
) | safe
}}
</div>
<div class="col-3">
<h3 class="u-no-margin--bottom"><a class="p-heading--4 p-link--inverted" href="/maas/docs" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'REST API, CLI' });" aria-label="Link to manage command line interface page on MAAS documentation">See MAAS CLI on how to get started with the&nbsp;CLI&nbsp;&rsaquo;</a></h3>
</div>
</div>
</div>
<div class="col-6 p-takeunder is-dark" style="background-color: #666;">
<div class="row u-equal-height">
<div class="col-3 u-vertically-center">
<h3><a class="p-heading--4 p-link--inverted" href="/maas/docs/api" onclick="dataLayer.push({'event' : 'GAEvent', 'eventCategory' : 'Feature', 'eventAction' : 'Click', 'eventLabel' : 'REST API, CLI' });" aria-label="Link to application programming interface page on MAAS documentation">See the API documentation to automate and extend&nbsp;MAAS&nbsp;&rsaquo;</a></h3>
</div>
<div class="col-3 u-align--center u-hide--small">
{{
image(
url="https://assets.ubuntu.com/v1/a92a0e74-maas-api.svg",
alt="MAAS application programming interface icon",
width="150",
height="156",
hi_def=True,
) | safe
}}
</div>
</div>
</div>
</div>
</section>
<section class="p-strip--light is-bordered is-shallow">
<div class="row">
<div class="col-12">
<p class="p-heading--3">Want to understand the core concepts and get a high-level overview of MAAS and its architecture?</p>
<p class="u-no-margin--bottom"><a href="/maas/how-it-works" aria-label="Link to the how it works page on maas dot i o">Read how it works&nbsp;&rsaquo;</a></p>
</div>
</div>
</section>
<script src="{{ versioned_static('js/modules/venobox/venobox.min.js') }}"></script>
<script defer>
(function() {
new VenoBox();
})();
</script>
{% endblock %}

View File

@ -0,0 +1,40 @@
{% extends "base_index.html" %}
{% block title %}Tutorials{% endblock %}
{% block content %}
<section class="p-strip--image is-shallow" style="background-image: url('https://assets.ubuntu.com/v1/e54487e2-maas-docs-suru.png')">
<div class="u-fixed-width">
<h1 class="p-heading--2 u-no-margin--bottom">Tutorials</h1>
</div>
</section>
<section class="p-strip is-shallow">
<div class="row u-equal-height">
{% for item in tutorials %}
<div class="col-4 col-medium-3 p-card">
<div class="p-card__content">
<h3 class="p-heading--4">
<a href="{{ item.link }}">
{{ item.title | safe }}
</a>
</h3>
<p>{{ item.summary | safe }}</p>
</div>
<p>Difficulty: <span class="p-tutorials-meter p-tutorials-meter--{{ item.difficulty }}">{{ item.difficulty }} out of 5</span></p>
</div>
{% endfor %}
</div>
</section>
<section class="p-strip--light is-bordered is-shallow">
<div class="row">
<div class="col-12">
<p class="p-heading--three">Want to understand the core concepts and get a high-level overview of MAAS and its architecture?</p>
<p class="u-no-margin--bottom"><a href="/maas/how-it-works" aria-label="Link to the how it works page on maas dot i o">Read how it works&nbsp;&rsaquo;</a></p>
</div>
</div>
</section>
{% endblock %}

View File

@ -25,6 +25,8 @@ from canonicalwebteam.discourse import (
Docs,
DocParser,
EngagePages,
TutorialParser,
Tutorials,
)
from canonicalwebteam.search import build_search_view
import canonicalwebteam.directory_parser as directory_parser
@ -1148,6 +1150,131 @@ app.add_url_rule(
dqlite_docs.init_app(app)
MAAS_DISCOURSE_API_KEY = os.getenv("MAAS_DISCOURSE_API_KEY")
MAAS_DISCOURSE_API_USERNAME = os.getenv("MAAS_DISCOURSE_API_USERNAME")
maas_url_prefix = "/maas/docs"
maas_docs = Docs(
parser=DocParser(
api=DiscourseAPI(
base_url="https://discourse.maas.io/",
session=search_session,
get_topics_query_id=2,
api_key=MAAS_DISCOURSE_API_KEY,
api_username=MAAS_DISCOURSE_API_USERNAME,
),
index_topic_id=6662,
url_prefix=maas_url_prefix,
tutorials_index_topic_id=1289,
tutorials_url_prefix="/maas",
),
document_template="maas/docs/document.html",
url_prefix=maas_url_prefix,
)
app.add_url_rule(
"/maas/docs/search",
"maas-docs-search",
build_search_view(
app=app,
session=search_session,
site="maas.io/docs",
template_path="/maas/docs/search-result.html",
),
)
maas_docs.init_app(app)
tutorials_discourse = Tutorials(
parser=TutorialParser(
api=DiscourseAPI(
base_url="https://discourse.maas.io/",
session=search_session,
api_key=MAAS_DISCOURSE_API_KEY,
api_username=MAAS_DISCOURSE_API_USERNAME,
get_topics_query_id=2,
),
index_topic_id=1289,
url_prefix="/maas/tutorials",
),
document_template="maas/_tutorial.html",
url_prefix="/maas/tutorials",
blueprint_name="maas-tutorials",
)
@app.route("/maas/tutorials")
def maas_tutorials():
tutorials_discourse.parser.parse()
tutorials_discourse.parser.parse_topic(
tutorials_discourse.parser.index_topic
)
tutorials = tutorials_discourse.parser.tutorials
topic_list = []
for item in tutorials:
if item["categories"] not in topic_list:
topic_list.append(item["categories"])
item["categories"] = {
"slug": item["categories"],
"name": " ".join(
[word.capitalize() for word in item["categories"].split("-")]
),
}
topic_list.sort()
topics = []
for topic in topic_list:
topics.append(
{
"slug": topic,
"name": " ".join(
[word.capitalize() for word in topic.split("-")]
),
}
)
return flask.render_template(
"maas/tutorials.html",
tutorials=tutorials,
topics=topics,
)
tutorials_discourse.init_app(app)
MAAS_BLOG_URL = "/maas/blog"
maas_blog_api = BlogAPI(
session=search_session,
thumbnail_width=354,
thumbnail_height=199,
)
maas_blog = build_blueprint(
BlogViews(
api=maas_blog_api,
blog_title="MAAS Blog",
tag_ids=[1304],
excluded_tags=[3184, 3265, 3408],
),
)
app.register_blueprint(maas_blog, url_prefix=MAAS_BLOG_URL, name="maas_blog")
app.add_url_rule(
"/maas/blog/sitemap.xml",
view_func=BlogSitemapIndex.as_view(
"maas_blog_sitemap", blog_views=maas_blog
),
)
app.add_url_rule(
"/maas/blog/sitemap/<regex('.+'):slug>.xml",
view_func=BlogSitemapPage.as_view(
"maas_blog_sitemap_page", blog_views=maas_blog
),
)
@app.errorhandler(502)
def bad_gateway(e):

View File

@ -4978,6 +4978,11 @@ vanilla-framework@4.9.0:
resolved "https://registry.npmjs.org/vanilla-framework/-/vanilla-framework-4.9.0.tgz"
integrity sha512-iTmvqWlsX0ic69VZ1sR9NPQtYRR9+iM679HZCl7SDQhMQSsEeJEQ6Ejjen3JN5a7YxiYmeIhxaLlmC4rExRT1w==
venobox@2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/venobox/-/venobox-2.1.8.tgz#372b92194fb33dd90548dcd2fde70c3f84b099be"
integrity sha512-GfT2ejBfdwgTJ02XhoZY9zz+f6OD3+R1IaCy1kxhaDbvchZLNgunbPhq6k69/4jqGlQvwa+sxvufhR9A8UQyKQ==
verbalize@^0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/verbalize/-/verbalize-0.1.2.tgz"