Skip to content

Commit

Permalink
Merge pull request #717 from gkadillak/issue#697-sharpen-rockons
Browse files Browse the repository at this point in the history
Issue#697 sharpen rockons
  • Loading branch information
schakrava committed Jul 6, 2015
2 parents 16e6385 + 9eeb516 commit 8d89381
Show file tree
Hide file tree
Showing 15 changed files with 58 additions and 39 deletions.
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
'ovpn-initpki = ovpn_util:initpki',
'ovpn-client-gen = ovpn_util:client_gen',
'ovpn-client-print = ovpn_util:client_retrieve',
'qgroup-clean = qgroup_clean:main',
'rockon-json = rockon_util:main',
],
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,34 @@
<div class="col-md-10">
<label class="control-label"></label>
<div class="form-box">
<form id="vol-select-form" name="aform" >
<form id="vol-select-form" name="aform" class="form-horizontal">
<div class="messages"></div>
<% if (shares.length == 0) { %>
<h3>There are no Shares left to add. Create a new one and try again.</h3>
<% } else { %>
<div class="form-group">
<label class="control-label" for="shares">Share *</label>
<div class="controls pull-right">
<select <a name=""></a>="share" id="share" data-placeholder="Select shares to export">
<label class="col-sm-3 control-label" for="shares">Storage <span class="required">*</span></label>
<div class="controls col-sm-5">
<select class="form-control" id="share" name="share" data-placeholder="Select shares to export">
<option></option>
<% _.each(shares, function(share) { %>
<option value="<%= share.get('name') %>"><%= share.get('name') %></option>
<% }); %>
</select>
</div>
<br>
<label class="control-label" for="volumes">Rock-on directory *</label>
<div class="controls pull-right">
<input type="text" id="volume" name="volume" title="Absolute path of the directory to make this Share visible inside the Rock-on. Eg: /data/media">
<i class="fa fa-info-circle fa-lg" title="Select a Share that you want to assign to this Rock-on"></i>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="volumes">Rock-on directory <span class="required">*</span></label>
<div class="controls col-sm-5">
<input class="form-control" type="text" id="volume" name="volume">
</div>
<i class="fa fa-info-circle fa-lg" title="Provide an absolute directory path inside the Rock-on. Selected Share will be available to the Rock-on at this location. Eg: /data/media"></i>
</div>
<% } %>
</form>
</div>
<% } %>
</form>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</div>
</div>
<div class="alert alert-warning">
<p>Additional configuration is needed for this Rock-on. Make sure to read tooltips for specific information before making your selection.</p>
<p>Additional configuration is needed for this Rock-on. Read mouseover <i class="fa fa-info-circle"></i> tooltips for specific information before making your selection.</p>
</div>

<div id="ph-cc-form"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 25%;"></div>
</div>
<div class="alert alert-warning">
<p>Shares provide storage to the Rock-on. Make sure to read tooltips for specific information before making a selection. We strongly recommend creating dedicated Share assignments. If a Share is assigned to more than one Rock-On, it could cause strange behavior.</p>
<p>Shares provide storage to the Rock-on. Read mousever <i class="fa fa-info-circle"></i> tooltips for specific information before making a selection. We strongly recommend creating dedicated Share assignments. If a Config or Data Share is assigned to more than one Rock-on, it could cause strange behavior.</p>
</div>
<div id="ph-vols-table"></div>
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div class="alert alert-success">
<p>Installation is in progress.<br>It can take a while depending on the type of Rock-on, network speed and other factors.<br> You can monitor the Rock-ons page which refreshes periodically during the installation.</p>
<div class="alert alert-info">
Installation is in progress. It can take a while depending on the type of Rock-on, network speed and other factors. You can monitor the Rock-ons page which refreshes periodically during the installation.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
</div>
</div>
<div class="alert alert-warning">
<p>Ports provide network access to the Rock-on. Preferred default values are provided for convenience. Read tooltips for more information.</p>
<p>Ports provide network access to the Rock-on. Preferred default values are provided for convenience. Read mouseover <i class="fa fa-info-circle"></i> tooltips for more information.</p>
</div>
<div id="ph-ports-form"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<div class="form-group">
<label class="control-label col-sm-3" for="shares"><%= volume.get('label') %> <span class="required">*</span></label>
<div class="col-sm-5">
<select required="true" class="form-control" name="<%= volume.id %>" id="<%= volume.id %>" data-placeholder="Select shares to export">
<select class="form-control" name="<%= volume.id %>" id="<%= volume.id %>" data-placeholder="Select shares to export">
<option></option>
<% shares.each(function(share, index) { %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ RockonsView = RockstorLayoutView.extend({
if (buttonDisabled(button)) return false;
var rockon_id = button.attr('data-name');
var rockon_o = _this.rockons.get(rockon_id);
if (confirm("Are you sure you want to uninstall this Rockon(" + rockon_o.get('name') + ")?")) {
if (confirm("Are you sure you want to uninstall this Rock-on (" + rockon_o.get('name') + ")?")) {
disableButton(button);
$.ajax({
url: '/api/rockons/' + rockon_id + '/uninstall',
Expand Down Expand Up @@ -693,12 +693,12 @@ RockonSettingsWizardView = WizardView.extend({
modifyButtonText: function() {
if (this.currentPageNum == 0) {
this.$('#prev-page').hide();
this.$('#next-page').html('Add a Share');
this.$('#next-page').html('Add Storage');
if (!this.rockon.get('volume_add_support')) {
this.$('#next-page').hide();
}
} else if (this.currentPageNum == (this.pages.length - 2)) {
this.$('#prev-page').html('Add a Share');
this.$('#prev-page').html('Add Storage');
this.$('#next-page').html('Next');
} else if (this.currentPageNum == (this.pages.length - 1)) {
this.$('#prev-page').hide();
Expand Down Expand Up @@ -759,8 +759,10 @@ RockonAddShare = RockstorWizardPage.extend({
}));
this.share_form = this.$('#vol-select-form');
this.validator = this.share_form.validate({
rules: { "volume": "required" },
messages: { "volume": "Must be a valid unix path. Eg: /data/media" }
rules: { "volume": "required",
"share": "required" },
messages: { "volume": "Must be a valid unix path. Eg: /data/media",
"share": "Select an appropriate Share to map"}
});
return this;
},
Expand Down
1 change: 1 addition & 0 deletions src/rockstor/storageadmin/templates/storageadmin/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="http://rockstor.com/media/images/ico/favicon.ico">
<title>RockStor | {% block title %}{% endblock %}</title>
<link href="/static/storageadmin/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/storageadmin/css/datepicker.css" rel="stylesheet">
Expand Down
3 changes: 3 additions & 0 deletions src/rockstor/storageadmin/views/rockon.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ def post(self, request, command=None):
options = containers[c]['opts']
id_l = []
for o in options:
#there are no unique constraints on this model, so we need this bandaid.
if (ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).count() > 1):
ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).delete()
oo, created = ContainerOption.objects.get_or_create(container=co,
name=o[0],
val=o[1])
Expand Down
2 changes: 1 addition & 1 deletion src/rockstor/storageadmin/views/rockon_custom_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get_queryset(self, *args, **kwargs):
try:
rockon = RockOn.objects.get(id=self.kwargs['rid'])
except:
e_msg = ('Rockon(%s) does not exist' % self.kwargs['rid'])
e_msg = ('Rock-on(%s) does not exist' % self.kwargs['rid'])
handle_exception(Exception(e_msg), self.request)

return DCustomConfig.objects.filter(rockon=rockon)
10 changes: 7 additions & 3 deletions src/rockstor/storageadmin/views/rockon_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def get_queryset(self, *args, **kwargs):
@staticmethod
def _pending_check(request):
if (RockOn.objects.filter(state__contains='pending').exists()):
e_msg = ('Another Rockon is in state transition. Multiple '
'simultaneous Rockon transitions are not '
e_msg = ('Another Rock-on is in state transition. Multiple '
'simultaneous Rock-on transitions are not '
'supported. Please try again later.')
handle_exception(Exception(e_msg), request)

Expand Down Expand Up @@ -100,7 +100,7 @@ def post(self, request, rid, command):
if (DPort.objects.filter(hostp=p).exists()):
po = DPort.objects.get(hostp=p)
if (po.container.rockon.id != rockon.id):
e_msg = ('Rockon port(%s) is dedicated to '
e_msg = ('Rock-on port(%s) is dedicated to '
'another Rock-On(%s) and cannot '
'be changed. Choose a different name'
% (p, po.container.rockon.name))
Expand Down Expand Up @@ -162,6 +162,10 @@ def post(self, request, rid, command):
if (DVolume.objects.filter(container=co, dest_dir=s).exists()):
e_msg = ('Directory(%s) is already mapped for this Rock-on' % s)
handle_exception(Exception(e_msg), request)
if (not s.startswith('/')):
e_msg = ('Invalid Directory(%s). Must provide an '
'absolute path. Eg: /data/media' % s)
handle_exception(Exception(e_msg), request)
do = DVolume(container=co, share=so, uservol=True, dest_dir=s)
do.save()
rockon.state = 'pending_update'
Expand Down
25 changes: 13 additions & 12 deletions src/rockstor/storageadmin/views/rockon_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
'description': 'Open Source VPN server',
'website': 'https://openvpn.net/',
'icon': 'https://openvpn.net/',
'more_info': '<h4>Additional steps are required by this Rockon.</h4><p>Run these following commands as the<code>root</code>user on your Rockstor system.</p><h4><u>Initialize PKI</u>&nbsp;&nbsp;&nbsp;&nbsp;<i>Rock-on will not start without it.</i></h4><code>/opt/rockstor/bin/ovpn-initpki</code><h4><u>Generate a client certificate</u>&nbsp;&nbsp;&nbsp;&nbsp;<i>One for every client</i></h4><code>/opt/rockstor/bin/ovpn-client-gen</code><br><h4><u>Retrieve client configuration</u>&nbsp;&nbsp;&nbsp;&nbsp<i>For any one of your clients. The resulting .ovpn file can be used to connect.</i></h4><code>/opt/rockstor/bin/ovpn-client-print</code><h4><u>Configure firewall</u></h4><p>If your Rockstor system is behind a firewall, you will need to configure it to allow OpenVPN traffic to forward to your Rockstor system.</p>',}
'more_info': '<h4>Additional steps are required by this Rock-on.</h4><p>Run these following commands as the<code>root</code>user on your Rockstor system, i.e., via a ssh console.</p><h4><u>Initialize PKI</u>&nbsp;&nbsp;&nbsp;&nbsp;<i>The OpenVPN Rock-on will not start without it.</i></h4><code>/opt/rockstor/bin/ovpn-initpki</code><h4><u>Generate a client certificate</u>&nbsp;&nbsp;&nbsp;&nbsp;<i>One for every client</i></h4><code>/opt/rockstor/bin/ovpn-client-gen</code><br><h4><u>Retrieve client configuration</u>&nbsp;&nbsp;&nbsp;&nbsp<i>For any one of your clients. The resulting .ovpn file can be used to connect to this OpenVPN server.</i></h4><code>/opt/rockstor/bin/ovpn-client-print</code><h4><u>Configure firewall</u></h4><p>If your Rockstor system is behind a firewall, you will need to configure it to allow OpenVPN traffic to forward to your Rockstor system.</p>',}

owncloud = {'ui': {'slug': '',
'https': True,},
Expand All @@ -37,16 +37,16 @@
'volumes': {'/var/www/owncloud/data':
{'description': 'Choose a Share for OwnCloud data. Eg: create a Share called owncloud-data for this purpose alone.',
'min_size': 1073741824,
'label': 'Data directory',},
'label': 'Data Storage',},
'/var/www/owncloud/config':
{'description': 'Choose a Share for OwnCloud configuration. Eg: create a Share called owncloud-config for this purpose alone.',
'label': 'Config directory',
'label': 'Config Storage',
'min_size': 1073741824,},},
'launch_order': 2,},
'owncloud-postgres': {'image': 'postgres',
'volumes': {'/var/lib/postgresql/data':
{'description': "Choose a Share for OwnCloud's postgresql database. Eg: create a Share called owncloud-db for this purpose alone.",
'label': 'Database',
'label': 'DB Storage',
'min_size': 1073741824, }, },
'launch_order': 1}, },
'container_links': {'owncloud': [{'source_container': 'owncloud-postgres',
Expand Down Expand Up @@ -84,13 +84,14 @@
'volumes': {'/home/syncthing/.config/syncthing':
{'description': 'Choose a Share for configuration. Eg: create a Share called syncthing-config for this purpose alone.',
'min_size': ONE_GB,
'label': 'Config directory',},
'label': 'Config Storage',},
'/home/syncthing/Sync':
{'label': 'Data directory',
{'label': 'Data Storage',
'description': 'Choose a Share for all incoming data. Eg: create a Share called syncthing-data for this purpose alone.',},},
'launch_order': 1,},},
'description': 'Continuous File Synchronization',
'website': 'https://syncthing.net/',}
'website': 'https://syncthing.net/',
'volume_add_support': True, }

transmission = {'ui': {'slug': '',},
'containers': {'transmission': {'image': 'dperson/transmission',
Expand All @@ -106,7 +107,7 @@
'description': 'Port used to share the file being downloaded. You may need to open it(protocol: tcp and udp) on your firewall. Suggested default: 51413.',},},
'volumes': {'/var/lib/transmission-daemon':
{'description': "Choose a Share where Transmission will save all of it's files including your downloads. Eg: create a Share called transmission-rockon.",
'label': 'Data directory',},},
'label': 'Data Storage',},},
'launch_order': 1,},},
'custom_config': {'TRUSER':
{'label': 'WebUI username',
Expand All @@ -132,12 +133,12 @@
'description': 'Port for incoming data. You may need to open it(protocol: udp) on your firewall. Suggested default: 3369.',},},
'volumes': {'/data':
{'description': 'Choose a Share for all incoming data. Eg: create a Share called btsync-data for this purpose alone. It will be available as /data inside BTSync.',
'label': 'Data directory',},},
'label': 'Data Storage',},},
'launch_order': 1,},},
'description': 'BitTorrent Sync',
'website': 'https://www.getsync.com/',
'volume_add_support': True,
'more_info': '<h4>Authentication</h4><p>Default username for your BTSync UI is<code>admin</code>and password is<code>password</code></p><h4>Storage</h4><p>We strongly recommend changing the Default folder location to<code>/data</code>in the UI preferences.</p><p>You can also assign additional Shares for custom organization of your data.</p>'}
'more_info': '<h4>Authentication</h4><p>Default username for your BTSync UI is<code>admin</code>and password is<code>password</code></p><h4>Storage</h4><p>You can also assign additional Shares for custom organization of your data.</p>'}

plex = {'ui': {'slug': 'web',},
'containers': {'plex': {'image': 'timhaak/plex',
Expand All @@ -151,10 +152,10 @@
'opts': [['--net=host', ''],],
'volumes': {'/config':
{'description': 'Choose a Share for Plex configuration. Eg: create a Share called plex-config for this purpose alone.',
'label': 'Config directory',},
'label': 'Config Storage',},
'/data':
{'description': 'Choose a Share for Plex content(your media). Eg: create a Share called plex-data for this purpose alone. You can also assign other media Shares on the system after installation.',
'label': 'Data directory',},},},},
'label': 'Data Storage',},},},},
'description': 'Plex media server',
'website': 'https://plex.tv/',
'volume_add_support': True,
Expand Down
2 changes: 1 addition & 1 deletion src/rockstor/storageadmin/views/rockon_port.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get_queryset(self, *args, **kwargs):
try:
rockon = RockOn.objects.get(id=self.kwargs['rid'])
except:
e_msg = ('Rockon(%s) does not exist' % self.kwargs['rid'])
e_msg = ('Rock-on(%s) does not exist' % self.kwargs['rid'])
handle_exception(Exception(e_msg), self.request)

containers = DContainer.objects.filter(rockon=rockon)
Expand Down
2 changes: 1 addition & 1 deletion src/rockstor/storageadmin/views/rockon_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get_queryset(self, *args, **kwargs):
try:
rockon = RockOn.objects.get(id=self.kwargs['rid'])
except:
e_msg = ('Rockon(%s) does not exist' % self.kwargs['rid'])
e_msg = ('Rock-on(%s) does not exist' % self.kwargs['rid'])
handle_exception(Exception(e_msg), self.request)

containers = DContainer.objects.filter(rockon=rockon)
Expand Down

0 comments on commit 8d89381

Please sign in to comment.