Skip to content

Commit

Permalink
Cleanup & Rename (#1)
Browse files Browse the repository at this point in the history
- s/components/component
- Load the driver name from package.json
- Use local npm-installed gulp instead of global
- Generate CSS and assets
- Update readme with more detail on usage
  • Loading branch information
vincent99 committed Apr 19, 2016
1 parent 8ba8d9f commit 096e17f
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 53 deletions.
39 changes: 26 additions & 13 deletions README.md
@@ -1,22 +1,35 @@
# ui-custom-driver-composer
A small utility to build custom UI for custom drivers added to the Rancher UI project
# ui-driver-skel
Skeleton Rancher UI driver for custom docker-machine drivers

## Setup

## Installation

* `git clone` this repository
* Fork this repository into your own account as `ui-driver-DRIVERNAME`
* DRIVERNAME should be the name of the driver that you would give to `docker-machine create --driver`, e.g. "mycompany", "digitalocean", "vultr", etc.
* Update the "name" in package.json to match
* You should also update description, URLs, etc, but these aren't strictly required.
* `npm install`
* `bower install`

## Running/Development

When developing an addon you may run the following command. Use the generated script as your custom UI script when adding a custom driver. This will allow you to develop locally.
* `gulp server`
* Visit your app at http://localhost:3000.
## Development

This package contains a small web-server that will serve up the custom driver UI at `https://localhost:3000/component.js`. You can run this while developing and point the Rancher settings there.
* `npm start`
* The driver name can be optionally overridden: `npm start -- --name=DRIVERNAME`
* The compiled files are viewable at http://localhost:3000.
* **Note:** The development server does not currently automatically restart when files are changed.

## Building

The script that is generated from the following command will be your custom UI component. Please read the comments in `components/component.js` for notes while working in the component. The script will be placed into the `dist` directory.
* `gulp build --name '<driver-name>'`
* `driver-name` should just be the dasherized name of your driver component and match the name you gave when saving a custom driver in Rancher UI.
For other users to see your driver, you need to build it and host the output on a server accessible from their browsers. GitHub releases are an easy choice.

* `npm build`
* Copy the contents of `dist` onto a webserver. If your Rancher is configured to use HA or SSL, the server must also be available via HTTPS.

## Using

* Add a Machine Driver in Rancher (Admin tab -> Settings -> Machine Drivers)
* Name: Your `DRIVERNAME` (see above).
* Download URL: The URL for the driver binary (e.g. `https://github.com/mycompany/docker-machine-mycompany/releases/download/v1.0.0/docker-machine-driver-mycompany-v1.0.0-linux-amd64.tar.gz`)
* Custom UI URL: The URL you uploaded the `dist` folder to, e.g. `https://github.com/mycompany/ui-driver-mycompany/releases/download/v1.0.0/component.js`)
* Wait for the driver to become "Active"
* Go to Infrastructure -> Hosts -> Add Host, your driver and custom UI should show up.
51 changes: 51 additions & 0 deletions assets/example.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions component/component.css
@@ -0,0 +1,3 @@
.machine-driver.%%DRIVERNAME%% {
background-image: url('example.svg');
}
52 changes: 52 additions & 0 deletions component/component.js
@@ -0,0 +1,52 @@
/* v----- Do not change anything between here
* (the DRIVERNAME placeholder will be automatically replaced during build) */
define('ui/components/drivers/driver-%%DRIVERNAME%%/component', ['exports', 'ember', 'ui/mixins/driver'], function (exports, _ember, _uiMixinsDriver) {

exports['default'] = _ember['default'].Component.extend(_uiMixinsDriver['default'], {
driverName: 'driver-%%DRIVERNAME%%',
/* ^--- And here */

// Write your component here, starting with setting 'model' to a machine with your config populated
bootstrap: function() {
let config = this.get('store').createRecord({
type : '%%DRIVERNAME%%Config',
size : 512,
});

this.set('model', this.get('store').createRecord({
type: 'machine',
'%%DRIVERNAME%%Config': config,
}));
}.on('init'),

// Add custom validation beyond what can be done from the config API schema
validate() {
// Get generic API validation errors
this._super();
var errors = this.get('errors')||[];

// Add more specific errors

// Check something and add an error entry if it fails:
if ( parseInt(this.get('model.%%DRIVERNAME%%Config.size'),10) < 1024 )
{
errors.push('Size must be at least 1024 MB');
}

// Set the array of errors for display,
// and return true if saving should continue.
if ( errors.get('length') )
{
this.set('errors', errors);
return false;
}
else
{
this.set('errors', null);
return true;
}
},

// Any computed properties or custom logic can go here
});
});
35 changes: 35 additions & 0 deletions component/template.hbs
@@ -0,0 +1,35 @@
<section class="horizontal-form">
<div class="container-fluid">
{{!-- This partial contains the quantity, name, and description fields --}}
{{partial "host/add-common"}}

<div class="over-hr r-mt20 r-mb20">
<span>My Skeleton Driver</span>
</div>

{{!-- An example input option --}}
<div class="row">
<div class="col-sm-12 col-md-2 form-label">
<label class="form-control-static">Size</label>
</div>
<div class="col-sm-12 col-md-4">
<div class="input-group">
{{input type="text"
class="form-control"
value=model.%%DRIVERNAME%%Config.size
}}
<span class="input-group-addon">MB</span>
</div>
</div>
</div>

{{!-- This partial contains the Labels and Advanced Options fields --}}
{{partial "host/add-options"}}
</div>

{{!-- This component shows errors produced by validate() in the component --}}
{{top-errors errors=errors}}

{{!-- This component shows the Create and Cancel buttons --}}
{{save-cancel save="save" cancel="cancel"}}
</section>
16 changes: 0 additions & 16 deletions components/component.js

This file was deleted.

1 change: 0 additions & 1 deletion components/template.hbs

This file was deleted.

51 changes: 35 additions & 16 deletions gulpfile.js
Expand Up @@ -8,21 +8,31 @@ const htmlbars = require('gulp-htmlbars-compiler');
const wrapAmd = require('gulp-wrap-amd');
const replace = require('gulp-replace');
const argv = require('yargs').argv;
const pkg = require('./package.json');

const NAME_TOKEN = '%%DRIVERNAME%%';
const NAME_LOWER_TOKEN = '%%DRIVERLOWERNAME%%';

const BASE = 'component/';
const DIST = 'dist/';
const TMP = 'tmp/';
let DRIVER_NAME = argv.name;
const ASSETS = 'assets/';
const DRIVER_NAME = argv.name || pkg.name.replace(/^ui-driver-/,'');

console.log('Driver Name:', DRIVER_NAME);

if (!DRIVER_NAME) {
console.log('Please include a driver name with the --name flag');
return false;
process.exit(1);
}

gulp.task('default', ['build']);

gulp.task('server', ['build'], function() {
return gulpConnect.server({
root: [DIST],
port: process.env.PORT || 3000
port: process.env.PORT || 3000,
https: true
});
});

Expand All @@ -31,39 +41,48 @@ gulp.task('clean', function() {
.pipe(clean());
});

gulp.task('js', ['clean'], function() {
gulp.task('js', function() {
return gulp.src([
'components/*.js'
BASE + '*.js'
])
.pipe(replace(
'<driver-name>', DRIVER_NAME
))
.pipe(replace(NAME_TOKEN, DRIVER_NAME))
.pipe(gulpConcat('component.js',{newLine: ';\n'}))
.pipe(gulp.dest(TMP));
});

gulp.task('templates', ['js'], function() {
return gulp.src('components/**/*.hbs')
gulp.task('css', function() {
return gulp.src([
BASE + '**.css'
])
.pipe(replace(NAME_TOKEN, DRIVER_NAME))
.pipe(gulpConcat('component.css',{newLine: ';\n'}))
.pipe(gulp.dest(DIST));
});

gulp.task('assets', function() {
return gulp.src(ASSETS+'*')
.pipe(gulp.dest(DIST));
});

gulp.task('compiled', ['js'], function() {
return gulp.src(BASE +'**/*.hbs')
.pipe(replace(NAME_TOKEN, DRIVER_NAME))
.pipe(htmlbars({compiler: emCompiler}))
.pipe(wrapAmd({
deps: ['exports', 'ember', 'ui/mixins/driver'],
params: ['exports', '_ember', '_uiMixinsDriver'],
moduleRoot: 'component/',
modulePrefix: 'ui/components/drivers/'
modulePrefix: 'ui/components/drivers/driver-' + DRIVER_NAME + '/'
}))
.pipe(replace(
"return Ember.TEMPLATES['template']", 'exports["default"]'
))
.pipe(replace(
'../components', DRIVER_NAME
))
.pipe(gulpConcat('template.js'), {newLine: ';\n'})
.pipe(gulp.dest(TMP));
});

gulp.task('build', ['templates'], function() {
gulp.task('build', ['compiled','css','assets'], function() {
return gulp.src([`${TMP}/*.js`])
.pipe(gulpConcat('component.js',{newLine: ';\n'}))
.pipe(gulp.dest(DIST));

});
20 changes: 13 additions & 7 deletions package.json
@@ -1,18 +1,24 @@
{
"name": "ui-custom-driver-composer",
"name": "ui-driver-skel",
"version": "0.0.1",
"description": "A small utility to build custom UI for custom drivers added to the Rancher UI project",
"description": "Skeleton Rancher UI driver for custom docker-machine drivers",
"scripts": {},
"repository": {
"type": "git",
"url": "git+https://github.com/westlywright/ui-custom-driver-composer.git"
"url": "git+https://github.com/rancher/ui-driver-skel.git"
},
"author": "",
"license": "MIT",
"author": "Rancher Labs, Inc.",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/westlywright/ui-custom-driver-composer/issues"
"url": "https://github.com/rancher/rancher/issues"
},
"homepage": "https://github.com/westlywright/ui-custom-driver-composer#readme",
"scripts": {
"start": "./node_modules/.bin/gulp server",
"clean": "./node_modules/.bin/gulp clean",
"build": "./node_modules/.bin/gulp build",
"upload": "./scripts/upload"
},
"homepage": "https://github.com/rancher/ui-driver-skel#readme",
"devDependencies": {
"del": "^2.2.0",
"gulp": "^3.9.1",
Expand Down

0 comments on commit 096e17f

Please sign in to comment.