Switch landing page to read template from S3 bucket

This change uses CORS to make the Angular template request to a defined S3 bucket, falling back to the compiled login template if the bucket is not available.

Fixes #1313
This commit is contained in:
Joseph Schorr 2016-11-29 18:19:06 -05:00
parent b7aac159ae
commit 66e09b2a95
4 changed files with 28 additions and 251 deletions

View file

@ -19,7 +19,8 @@ CLIENT_WHITELIST = ['SERVER_HOSTNAME', 'PREFERRED_URL_SCHEME', 'MIXPANEL_KEY',
'STRIPE_PUBLISHABLE_KEY', 'ENTERPRISE_LOGO_URL', 'SENTRY_PUBLIC_DSN',
'AUTHENTICATION_TYPE', 'REGISTRY_TITLE', 'REGISTRY_TITLE_SHORT',
'CONTACT_INFO', 'AVATAR_KIND', 'LOCAL_OAUTH_HANDLER', 'DOCUMENTATION_LOCATION',
'DOCUMENTATION_METADATA', 'SETUP_COMPLETE', 'DEBUG', 'MARKETO_MUNCHKIN_ID']
'DOCUMENTATION_METADATA', 'SETUP_COMPLETE', 'DEBUG', 'MARKETO_MUNCHKIN_ID',
'STATIC_SITE_BUCKET']
def frontend_visible_config(config_dict):
@ -395,3 +396,6 @@ class DefaultConfig(object):
# Delays workers from starting until a random point in time between 0 and their regular interval.
STAGGER_WORKERS = True
# Location of the static marketing site.
STATIC_SITE_BUCKET = None

View file

@ -118,54 +118,41 @@ angular.module('quay').directive('quayClasses', function(Features, Config) {
});
/**
* Adds a quay-include attribtue that adds a template solely if the expression evaluates to true.
* Automatically adds the Features and Config services to the scope.
* Adds a quay-static-include attribute handles adding static marketing content from a defined
* S3 bucket. If running under QE, the local template is used.
*
Usage: quay-include="{'Features.BILLING': 'partials/landing-normal.html', '!Features.BILLING': 'partials/landing-login.html'}"
* Usage: quay-static-include="{'hosted': 'index.html', 'otherwise': 'partials/landing-login.html'}"
*/
angular.module('quay').directive('quayInclude', function($compile, $templateCache, $http, Features, Config) {
angular.module('quay').directive('quayStaticInclude', function($compile, $templateCache, $http, Features, Config) {
return {
priority: 595,
restrict: 'A',
link: function($scope, $element, $attr, ctrl) {
var getTemplate = function(templateName) {
var templateUrl = '/static/' + templateName;
return $http.get(templateUrl, {cache: $templateCache});
var getTemplate = function(hostedTemplateName, staticTemplateName) {
var staticTemplateUrl = '/static/' + staticTemplateName;
var templateUrl = staticTemplateUrl;
if (Features.BILLING && Config['STATIC_SITE_BUCKET']) {
templateUrl = Config['STATIC_SITE_BUCKET'] + hostedTemplateName;
}
return $http.get(templateUrl, {cache: $templateCache}).catch(function(resolve, reject) {
// Fallback to the static local URL if the hosted URL doesn't work.
return $http.get(staticTemplateUrl, {cache: $templateCache});
});
};
var result = $scope.$eval($attr.quayInclude);
var result = $scope.$eval($attr.quayStaticInclude);
if (!result) {
return;
}
var scopeVals = {
'Features': Features,
'Config': Config
};
var templatePath = null;
for (var expr in result) {
if (!result.hasOwnProperty(expr)) { continue; }
// Evaluate the expression with the entire features list added.
var value = $scope.$eval(expr, scopeVals);
if (value) {
templatePath = result[expr];
break;
}
}
if (!templatePath) {
return;
}
var promise = getTemplate(templatePath).success(function(html) {
$element.html(html);
}).then(function (response) {
$element.replaceWith($compile($element.html())($scope));
var promise = getTemplate(result['hosted'], result['otherwise']).then(function (response) {
$element.replaceWith($compile(response['data'])($scope));
if ($attr.onload) {
$scope.$eval($attr.onload);
}
}).catch(function(err) {
console.log(err)
});
}
};

View file

@ -1,215 +0,0 @@
<div class="jumbotron landing">
<div class="landing-background"></div>
<div class="landing-content">
<h1>Quay <span class="bracket hidden-xs">[</span><span class="highlight">builds, analyzes, distributes</span><span class="bracket hidden-xs">]</span> your container images</h1>
<div class="buttons">
<a href="/plans?trial-plan=free" class="btn highlighted">Try it for free</a>
<a href="/plans" class="btn">View plans</a>
</div>
<div class="works-with">
<span class="text">Works with</span>
<span class="works-logo"><img src="/static/img/docker-white-custom.png"></span>
<span class="works-logo"><img src="/static/img/rkt-horizontal-white.svg"></span>
<span class="supports">Supports container image formats for both Docker and rkt</span>
</div>
</div>
</div> <!-- jumbotron -->
<div class="rows">
<div class="landing-section">
<h3>Trusted by companies of all sizes</h3>
<div class="cor-container">
<div class="row">
<div class="trusted-logos-large">
<div class="col-lg-2 col-lg-offset-2 col-md-3 col-sm-3 col-xs-6 trusted-logo-large">
<a href="http://www.jpl.nasa.gov/" ng-safenewtab alt="JPL"><img src="/static/img/logos/jpl-logo.png"></a>
</div>
<div class="col-lg-2 col-md-3 col-sm-3 col-xs-6 trusted-logo-large">
<a href="https://www.intuit.com" ng-safenewtab alt="Intuit"><img src="/static/img/logos/intuit-logo.gif"></a>
</div>
<div class="col-lg-2 col-md-3 col-sm-3 col-xs-6 trusted-logo-large">
<a href="http://www.ebay.com" ng-safenewtab alt="eBay"><img src="/static/img/logos/ebay-logo.png"></a>
</div>
<div class="col-lg-2 col-md-3 col-sm-3 col-xs-6 trusted-logo-large">
<a href="http://www.hotels.com" ng-safenewtab alt="Hotels.com"><img src="/static/img/logos/hotelscom-logo.jpg"></a>
</div>
</div>
</div> <!-- /row -->
<div class="row" style="margin-top: 40px;">
<div class="trusted-logos-medium">
<div class="col-lg-1 col-lg-offset-3 col-md-2 col-sm-2 col-xs-6 trusted-logo-medium">
<a href="http://www.qualcomm.com" ng-safenewtab alt="Qualcomm"><img src="/static/img/logos/qualcomm-logo.png"></a>
</div>
<div class="col-lg-1 col-md-2 col-sm-2 col-xs-6 trusted-logo-medium">
<a href="http://www.yammer.com" ng-safenewtab alt="Yammer"><img src="/static/img/logos/yammer-logo.png"></a>
</div>
<div class="col-lg-1 col-md-2 col-sm-2 col-xs-6 trusted-logo-medium">
<a href="http://www.autodesk.com/" ng-safenewtab alt="Autodesk"><img src="/static/img/logos/autodesk-logo-color-text-black-rgb-large.png"></a>
</div>
<div class="col-lg-1 col-md-2 col-sm-2 col-xs-6 trusted-logo-medium">
<a href="http://www.golfchannel.com" ng-safenewtab alt="Golf Channel"><img src="/static/img/logos/golfchannel-logo.png"></a>
</div>
<div class="col-lg-1 col-md-2 col-sm-2 col-xs-6 trusted-logo-medium">
<a href="http://travis-ci.org" ng-safenewtab alt="Travis CI"><img src="/static/img/logos/travisci-logo.png"></a>
</div>
<div class="col-lg-1 col-md-2 col-sm-2 col-xs-6 trusted-logo-medium">
<a href="http://www.twc.com" ng-safenewtab alt="Time Warner Cable"><img src="/static/img/logos/twc-logo.png"></a>
</div>
</div>
</div> <!-- /row -->
</div>
</div> <!-- -->
<div class="landing-section">
<h2>Built with our users in mind</h2>
<div class="cor-container">
<div class="row">
<div class="col-lg-8 feature-shoutout">
<img id="screenshot" ng-src="{{ '/static/img/' + currentScreenshot + '.png' }}" class="img-responsive">
</div>
<div class="col-lg-4">
<div class="screenshot-feature" ng-class="currentScreenshot == 'repo-view' ? 'active' : ''" ng-click="changeScreenshot('repo-view')">
<i class="fa fa-hdd-o"></i>
<span class="sf-title">Beautiful repository view</span>
<div class="sf-text">
Repository is presented with the maximum amount of useful information, including a full tags list,
markdown based description and repository push and pull counts.
</div>
</div>
<div class="screenshot-feature" ng-class="currentScreenshot == 'repo-tags' ? 'active' : ''" ng-click="changeScreenshot('repo-tags')">
<i class="fa fa-tags"></i>
<span class="sf-title">Repository Operations</span>
<div class="sf-text">
Operations on a repository can be performed directly from the user interface, including adding,
removing, and reverting tags.
</div>
</div>
<div class="screenshot-feature" ng-class="currentScreenshot == 'repo-settings' ? 'active' : ''" ng-click="changeScreenshot('repo-settings')">
<i class="fa fa-group"></i>
<span class="sf-title">Share at your control</span>
<div class="sf-text">
Set up the exact permissions your team, organization or business needs. Need to grant external access? Create one or more robot accounts to restrict access.
</div>
</div>
<div class="screenshot-feature" ng-class="currentScreenshot == 'build-history' ? 'active' : ''" ng-click="changeScreenshot('build-history')">
<i class="fa fa-tasks"></i>
<span class="sf-title">Dockerfile Build</span>
<div class="sf-text">
Repositories can be linked to GitHub, BitBucket, GitLab or custom git repositories, with automatic building of the Dockerfile(s) found on push.
</div>
</div>
</div>
</div>
</div>
</div> <!-- -->
<div class="landing-section">
<h2>Seamlessly integrate into your Docker-based infrastructure</h2>
<div class="cor-container">
<div class="row testimonial">
<div class="message">
Quay has become an essential part of our infrastructure as we move to Docker-based deploys.
The support and service that the Quay team provides is phenomenal. We couldn't do it without them!
</div>
<div class="speaker-info">
<img src="/static/img/testimonial-mike.png">
<span class="speaker-info-internal">
<span class="speaker">Mike Saffitz</span>
<span class="speaker-title"><a href="http://www.apptentive.com" ng-safenewtab alt="Apptentive">Apptentive</a> - CTO & Co-Founder</span>
</span>
</div>
<a class="learn-more" href="/tour">Learn more</a>
</div>
</div>
</div> <!-- -->
<div class="landing-section">
<h2>See what other people are saying about Quay</h2>
<div class="cor-container">
<div class="row">
<div class="jcarousel-wrapper">
<div class="jcarousel">
<ul>
<li>
<div class="twitter-view" avatar-url="https://pbs.twimg.com/profile_images/3320588708/9237d8d056e9ce2fa737ea7ab2de345b_bigger.jpeg"
author-name="Ross Timson" author-user="rosstimson" message-url="https://twitter.com/rosstimson/statuses/451052618685882368"
message-date="April 1, 2014">
Pushing Dockerfile changes to Github and having <a href="https://twitter.com/quayio">@quayio</a> build the
<a href="https://twitter.com/docker">@docker</a> image/container for you is extremely awesome.
</div>
</li>
<li>
<div class="twitter-view" avatar-url="https://pbs.twimg.com/profile_images/483391930147954688/pvJAHzy__bigger.jpeg"
author-name="Frank Macreery" author-user="fancyremarker" message-url="https://twitter.com/fancyremarker/statuses/448528623692025857"
message-date="March 25, 2014">
<a href="https://twitter.com/quayio">@quayio</a> releases Docker build flair! <a href="http://t.co/72ULgveLj4">pic.twitter.com/72ULgveLj4</a>
</div>
</li>
<li>
<div class="twitter-view" avatar-url="https://pbs.twimg.com/profile_images/438406731660394496/UKGDY6xB_bigger.jpeg"
author-name="Joshua Goldie" author-user="jdgoldie" message-url="https://twitter.com/jdgoldie/statuses/446622958040408064"
message-date="March 20, 2014">
Just started playing with <a href="https://twitter.com/quayio">@quayio</a> builds tied to
<a href="https://twitter.com/search?q=%23github&amp;src=hash">#github</a> repo. Really liking it. My first experiment:
<a href="https://t.co/2LgyagwTEq">https://t.co/2LgyagwTEq</a>
</div>
</li>
<li>
<div class="twitter-view" avatar-url="https://pbs.twimg.com/profile_images/378800000731516813/e70eae6c4a2c25ae516660e958b3d36b_bigger.jpeg"
author-name="Evan Hazlett" author-user="ehazlett" message-url="https://twitter.com/ehazlett/statuses/442351806161510400"
message-date="March 8, 2014">
Great guys <a href="https://twitter.com/quayio">@quayio</a>. If you havent tried it, do.
</div>
</li>
<li>
<div class="twitter-view" avatar-url="https://pbs.twimg.com/profile_images/463168904320122880/lQG69Wqk_bigger.jpeg"
author-name="Jon Morehouse" author-user="JonMorehouse" message-url="https://twitter.com/JonMorehouse/statuses/441719785055739904"
message-date="March 6, 2014">
<a href="https://twitter.com/quayio">@quayio</a> has awesome support.
<a href="https://twitter.com/search?q=%23awesomeTool&amp;src=hash">#awesomeTool</a>
<a href="https://twitter.com/search?q=%23awesomeTeam&amp;src=hash">#awesomeTeam</a>
</div>
</li>
</ul>
</div>
<a href="#" class="jcarousel-control jcarousel-control-prev">&lsaquo;</a>
<a href="#" class="jcarousel-control jcarousel-control-next">&rsaquo;</a>
<p class="jcarousel-pagination"></p>
</div>
</div>
<div class="row">
<div class="col-md-12 follow-button">
<iframe allowtransparency="true" frameborder="0" scrolling="no"
src="//platform.twitter.com/widgets/follow_button.html?screen_name=quayio&show_count=false"
style="width:120px; height:20px;"></iframe>
</div>
</div>
</div>
</div>
<div class="landing-section">
<h2>Start pushing to Quay in under a minute</h2>
<div class="cor-container">
<div class="row landing-action">
<a href="/plans?trial-plan=free" class="btn btn-primary">Try it for free</a>
</div>
</div>
</div>
<div class="landing-section" style="padding: 10px; padding-bottom: 0px;">
<a href="https://mixpanel.com/f/partner"><img src="//cdn.mxpnl.com/site_media/images/partner/badge_light.png" alt="Mobile Analytics" /></a>
</div>
</div>

View file

@ -1,3 +1,4 @@
<div quay-include="{'Features.BILLING': 'partials/landing-normal.html', '!Features.BILLING': 'partials/landing-login.html'}" onload="chromify()">
<span class="quay-spinner"></span>
<div quay-static-include="{'hosted': 'index.html', 'otherwise': 'partials/landing-login.html'}"
onload="chromify()">
<span class="cor-loader"></span>
</div>