mirror of
https://github.com/semaphoreui/semaphore.git
synced 2024-11-23 20:35:24 +01:00
Update site layout
- Add Dockerfile - Add docker instructions to README.md - Reorganise js & jade files
This commit is contained in:
parent
52d373e7a7
commit
58d8158116
11
Dockerfile
Normal file
11
Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM iojs:onbuild
|
||||
|
||||
ENV NODE_ENV production
|
||||
|
||||
ADD . /srv/semaphore
|
||||
WORKDIR /srv/semaphore
|
||||
|
||||
RUN npm install
|
||||
CMD ["node", "/srv/semaphore/bin/semaphore"]
|
||||
|
||||
EXPOSE 80
|
74
README.md
74
README.md
@ -3,36 +3,63 @@ semaphore
|
||||
|
||||
Open Source Alternative to Ansible Tower
|
||||
|
||||
![](public/img/screenshot.png)
|
||||
![screenshot](public/img/screenshot.png)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
The basics of Ansible Tower, but in addition:
|
||||
|
||||
- Fast, Simple interface that doesn’t get in the way
|
||||
- Task output is streamed live via websocket
|
||||
- Free. MIT Licensed. Do what you want.
|
||||
- [x] Fast, Simple interface (not having to submit a million forms to get something simple done)
|
||||
- [x] Task output is streamed live via websocket
|
||||
- [x] Create inventories per playbook
|
||||
- [x] Add rsa keys (to authenticate git repositories)
|
||||
- [x] Run playbooks against specified hosts
|
||||
- [ ] Multiple Users support
|
||||
|
||||
How to run:
|
||||
-----------
|
||||
Docker quickstart
|
||||
-----------------
|
||||
|
||||
1. Install Vagrant
|
||||
2. Run `vagrant up`
|
||||
3. Open [localhost:3000](http://localhost:3000)
|
||||
1. Get Docker
|
||||
2. Run redis
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
--name=redisio \
|
||||
-v /var/lib/redisio:/var/lib/redis \
|
||||
-p 127.0.0.1:6379:6379 \
|
||||
castawaylabs/redis-docker
|
||||
```
|
||||
|
||||
3. Run mongodb
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
--name=mongodb \
|
||||
-v /var/lib/mongodb:/var/lib/mongodb \
|
||||
-p 127.0.0.1:6379:6379 \
|
||||
castawaylabs/mongo-docker
|
||||
```
|
||||
|
||||
4. Run semaphore
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
--name=semaphroe \
|
||||
--restart=always \
|
||||
--link redisio:redis \
|
||||
--link mongodb:mongo \
|
||||
-p 80:80 \
|
||||
castawaylabs/semaphore
|
||||
```
|
||||
|
||||
Development steps:
|
||||
|
||||
Install requirements:
|
||||
- node.js >= 0.11.x
|
||||
- an isolated environment (e.g. Docker / NodeGear)
|
||||
- ansible (the tool)
|
||||
- node.js / io.js
|
||||
- an isolated environment (e.g. Docker / Vagrant)
|
||||
- ansible
|
||||
- mongodb & redis
|
||||
- Sudo access (this might change). To run jobs, this tool writes private keys to /root/.ssh and copies playbook directories to /root/.
|
||||
|
||||
1. Copy `lib/credentials.default.json` to `lib/credentials.json` and customise, or export relevant environment variables
|
||||
2. `bower install`
|
||||
3. `node bin/semaphore`
|
||||
|
||||
Initial Login
|
||||
-------------
|
||||
@ -58,9 +85,22 @@ Use these variables to override the config.
|
||||
| SMTP_PASS | Mandrill smtp password | |
|
||||
| MONGODB_URL | Mongodb URL | `mongodb://127.0.0.1/semaphore` |
|
||||
|
||||
Vision and goals
|
||||
----------------
|
||||
|
||||
- Be able to specify environment information per playbook / per task
|
||||
- Schedule jobs
|
||||
- Email alerts
|
||||
>>>>>>> 1199a52... Update site layout
|
||||
|
||||
Note to Ansible guys
|
||||
--------------------
|
||||
|
||||
> Thanks very much for making Ansible, and Ansible Tower. It is a great tool!. Your UI is pretty horrible though, and so we'd be happy if you could learn and use parts of this tool in your Tower.
|
||||
|
||||
It would be amazing if this could be your `Community Edition` of Ansible Tower.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
@ -13,4 +13,4 @@
|
||||
"angular-couch-potato": "~0.1.1",
|
||||
"angular-ui-router": "~0.2.10"
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ var express = require('express')
|
||||
|
||||
exports.unauthorized = function (app, template) {
|
||||
template([
|
||||
'tasks',
|
||||
'jobs',
|
||||
'hosts',
|
||||
'view'
|
||||
], {
|
||||
prefix: 'playbook'
|
||||
|
@ -27,19 +27,12 @@ html
|
||||
li: a(ui-sref="addPlaybook") Add Playbook
|
||||
|
||||
.container-fluid
|
||||
.row
|
||||
.col-sm-3.col-lg-2
|
||||
ul.nav
|
||||
h2.no-top-margin Playbooks
|
||||
li(ng-repeat="playbook in playbooks")
|
||||
a(ui-sref="playbook.view({ playbook_id: playbook._id })") {{ playbook.name }}
|
||||
|
||||
.col-sm-9.col-lg-10
|
||||
block content
|
||||
ui-view(autoscroll="false")
|
||||
p.lead.text-center
|
||||
i.fa.fa-spin.fa-cog
|
||||
| Loading...
|
||||
.col-lg-12
|
||||
block content
|
||||
ui-view(autoscroll="false")
|
||||
p.lead.text-center
|
||||
i.fa.fa-spin.fa-cog
|
||||
| Loading...
|
||||
|
||||
block js
|
||||
script(src="/vendor/requirejs/require.js" data-main="/js/semaphore.js")
|
||||
|
@ -1,4 +1,4 @@
|
||||
h2 Hosts
|
||||
h1 Hosts
|
||||
button.btn.btn-default.pull-right(ng-click="add()") Add Group
|
||||
|
||||
div(ng-repeat="hostgroup in hostgroups.hostgroups")
|
@ -1,4 +1,4 @@
|
||||
h2 Jobs
|
||||
h1 Jobs
|
||||
button.btn.btn-default.pull-right(ng-click="add()") Add Job
|
||||
|
||||
table.table.table-hover
|
@ -5,6 +5,6 @@ h1 Playbooks
|
||||
|
||||
table.table
|
||||
tr(ng-repeat="playbook in playbooks")
|
||||
td: a(ui-sref="playbook.view({ playbook_id: playbook._id })") {{ playbook.name }}
|
||||
td: a(ui-sref="playbook.tasks({ playbook_id: playbook._id })") {{ playbook.name }}
|
||||
|
||||
blockquote Playbooks are ansible playbooks. Each playbook defines a git repository with the playbook code. Semaphore downloads the playbook and runs the task file.
|
@ -1,4 +1,4 @@
|
||||
h2 Tasks
|
||||
h1 Tasks
|
||||
small(ng-if="status.length > 0" ng-bind="status")
|
||||
|
||||
table.table.table-hover
|
@ -1,16 +1,16 @@
|
||||
h1 {{ playbook.data.name }}
|
||||
.btn-group.pull-right
|
||||
button.btn.btn-success(ui-sref="playbook.edit({ playbook_id: playbook.data._id })") Edit
|
||||
button.btn.btn-danger(ng-click="delete()") Delete
|
||||
mixin menuItem(state, name)
|
||||
li(ng-class="{ active: $state.includes('#{state}') }"): a(ui-sref=state+"({ playbook_id: playbook.data._id })")= name
|
||||
|
||||
hr
|
||||
|
||||
ui-view(name="tasks")
|
||||
|
||||
hr
|
||||
|
||||
ui-view(name="jobs")
|
||||
|
||||
hr
|
||||
|
||||
ui-view(name="hosts")
|
||||
.row
|
||||
.col-sm-3.col-lg-2
|
||||
ul.nav
|
||||
h2.no-top-margin {{ playbook.data.name }}
|
||||
+menuItem("playbook.tasks", "Tasks")
|
||||
+menuItem("playbook.jobs", "Jobs")
|
||||
+menuItem("playbook.hosts", "Hosts")
|
||||
br
|
||||
ul.nav
|
||||
li: a(ui-sref="playbook.edit({ playbook_id: playbook.data._id })") Edit
|
||||
li: a(ng-click="delete()") Delete
|
||||
.col-sm-9.col-lg-10
|
||||
ui-view
|
@ -22,7 +22,6 @@
|
||||
- runit
|
||||
- npm: name={{ item }} global=yes
|
||||
with_items:
|
||||
- grunt-cli
|
||||
- bower
|
||||
|
||||
# source is copied using ansible.
|
||||
|
@ -28,4 +28,10 @@ h1, h2, h3, h4, h5, h6 {
|
||||
&.no-top-margin {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul.nav {
|
||||
& > li.active a {
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
@ -5,10 +5,10 @@ define([
|
||||
'factories/hostgroup',
|
||||
'factories/host'
|
||||
], function(app, $) {
|
||||
app.registerController('HostsCtrl', ['$scope', '$state', 'hostgroups', 'Host', function($scope, $state, hostgroups, Host) {
|
||||
|
||||
app.registerController('PlaybookHostsCtrl', ['$scope', '$state', 'hostgroups', 'Host', function($scope, $state, hostgroups, Host) {
|
||||
|
||||
$scope.hostgroups = hostgroups;
|
||||
|
||||
|
||||
hostgroups.get($scope.playbook, function () {
|
||||
});
|
||||
|
@ -4,9 +4,9 @@ define([
|
||||
'services/jobs',
|
||||
'factories/job'
|
||||
], function(app, $) {
|
||||
app.registerController('JobsCtrl', ['$scope', 'jobs', function($scope, jobs) {
|
||||
app.registerController('PlaybookJobsCtrl', ['$scope', 'jobs', function($scope, jobs) {
|
||||
$scope.jobs = jobs;
|
||||
|
||||
|
||||
jobs.get($scope.playbook, function () {
|
||||
});
|
||||
|
@ -7,9 +7,9 @@ define([
|
||||
], function(app, $, io) {
|
||||
var socket = io();
|
||||
|
||||
app.registerController('TasksCtrl', ['$scope', 'tasks', 'Task', function($scope, tasks, Task) {
|
||||
app.registerController('PlaybookTasksCtrl', ['$scope', 'tasks', 'Task', function($scope, tasks, Task) {
|
||||
$scope.tasks = tasks;
|
||||
|
||||
|
||||
tasks.get($scope.playbook, function () {
|
||||
});
|
||||
|
||||
@ -40,7 +40,7 @@ define([
|
||||
if (!task.data.output) {
|
||||
task.data.output = "";
|
||||
}
|
||||
|
||||
|
||||
task.data.output += data.output;
|
||||
|
||||
if (!$scope.$$phase) {
|
@ -30,10 +30,7 @@ define([
|
||||
controller: 'PlaybookCtrl',
|
||||
templateUrl: '/view/playbook/view',
|
||||
resolve: {
|
||||
dummy: $couchPotatoProvider.resolve(['controllers/playbook/playbook',
|
||||
'controllers/host/hosts',
|
||||
'controllers/job/jobs',
|
||||
'controllers/task/tasks']),
|
||||
dummy: $couchPotatoProvider.resolve(['controllers/playbook/playbook']),
|
||||
playbook: function (Playbook, $stateParams, $q, $state) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
@ -51,24 +48,6 @@ define([
|
||||
}
|
||||
})
|
||||
|
||||
.state('playbook.view', {
|
||||
url: '',
|
||||
views: {
|
||||
tasks: {
|
||||
templateUrl: '/view/task/tasks',
|
||||
controller: 'TasksCtrl'
|
||||
},
|
||||
jobs: {
|
||||
templateUrl: '/view/job/jobs',
|
||||
controller: 'JobsCtrl'
|
||||
},
|
||||
hosts: {
|
||||
templateUrl: '/view/host/hosts',
|
||||
controller: 'HostsCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('playbook.edit', {
|
||||
url: '/edit',
|
||||
templateUrl: "/view/playbook/add",
|
||||
@ -83,5 +62,30 @@ define([
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.state('playbook.tasks', {
|
||||
url: '/tasks',
|
||||
templateUrl: "/view/playbook/tasks",
|
||||
controller: 'PlaybookTasksCtrl',
|
||||
resolve: {
|
||||
dummy: $couchPotatoProvider.resolve(['controllers/playbook/tasks'])
|
||||
}
|
||||
})
|
||||
.state('playbook.jobs', {
|
||||
url: '/jobs',
|
||||
templateUrl: "/view/playbook/jobs",
|
||||
controller: 'PlaybookJobsCtrl',
|
||||
resolve: {
|
||||
dummy: $couchPotatoProvider.resolve(['controllers/playbook/jobs'])
|
||||
}
|
||||
})
|
||||
.state('playbook.hosts', {
|
||||
url: '/hosts',
|
||||
templateUrl: "/view/playbook/hosts",
|
||||
controller: 'PlaybookHostsCtrl',
|
||||
resolve: {
|
||||
dummy: $couchPotatoProvider.resolve(['controllers/playbook/hosts'])
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
@ -1 +0,0 @@
|
||||
vagrant ssh -- -R 27017:localhost:27017 -R 6379:localhost:6379 -R 3000:localhost:3000
|
Loading…
Reference in New Issue
Block a user