code => sub {
my ($param) = @_;
- my $config = PVE::INotify::read_file('interfaces');
+ my $rpcenv = PVE::RPCEnvironment::get();
+
+ my $tmp = PVE::INotify::read_file('interfaces', 1);
+ my $config = $tmp->{data};
+ my $changes = $tmp->{changes};
+
+ $rpcenv->set_result_attrib('changes', $changes) if $changes;
delete $config->{lo}; # do not list the loopback device
return PVE::RESTHandler::hash_to_array($config, 'iface');
}});
+__PACKAGE__->register_method({
+ name => 'revert_network_changes',
+ path => '',
+ method => 'DELETE',
+ permissions => {
+ check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
+ },
+ protected => 1,
+ description => "Revert network configuration changes.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => { type => "null" },
+ code => sub {
+ my ($param) = @_;
+
+ unlink "/etc/network/interfaces.new";
+
+ return undef;
+ }});
my $check_duplicate_gateway = sub {
my ($config, $newiface) = @_;
{ name => 'vzdump' },
{ name => 'ubcfailcnt' },
{ name => 'network' },
- { name => 'network_changes' },
{ name => 'aplinfo' },
];
return $res;
}});
-__PACKAGE__->register_method({
- name => 'network_changes',
- path => 'network_changes',
- method => 'GET',
- permissions => {
- check => ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
- },
- description => "Get network configuration changes (diff) since last boot.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => { type => "string" },
- code => sub {
- my ($param) = @_;
-
- my $res = PVE::INotify::read_file('interfaces', 1);
-
- return $res->{changes} || '';
- }});
-
-__PACKAGE__->register_method({
- name => 'revert_network_changes',
- path => 'network_changes',
- method => 'DELETE',
- permissions => {
- check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
- },
- protected => 1,
- description => "Revert network configuration changes.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => { type => "null" },
- code => sub {
- my ($param) = @_;
-
- unlink "/etc/network/interfaces.new";
-
- return undef;
- }});
-
__PACKAGE__->register_method({
name => 'status',
path => 'status',
me.create = !me.iface;
- var title;
var iface_vtype;
- if (me.create) {
- if (me.iftype === 'bridge') {
- title = "Create Bridge";
- iface_vtype = 'BridgeName';
- } else if (me.iftype === 'bond') {
- title = "Create Bond";
- iface_vtype = 'BondName';
- } else {
- throw "can't create unknown device type";
- }
+ if (me.iftype === 'bridge') {
+ me.subject = "Bridge";
+ iface_vtype = 'BridgeName';
+ } else if (me.iftype === 'bond') {
+ me.subject = "Bond";
+ iface_vtype = 'BondName';
} else {
- title = "Edit network device '" + me.iface + "'";
+ throw "no known network device type specified";
}
var column2 = [
var column1 = [
{
xtype: me.create ? 'textfield' : 'displayfield',
- fieldLabel: 'Name',
+ fieldLabel: gettext('Name'),
height: 22, // hack: set same height as text fields
name: 'iface',
value: me.iface,
{
xtype: 'pvetextfield',
deleteEmpty: !me.create,
- fieldLabel: 'IP address',
+ fieldLabel: gettext('IP address'),
vtype: 'IPAddress',
name: 'address'
},
{
xtype: 'pvetextfield',
deleteEmpty: !me.create,
- fieldLabel: 'Subnet mask',
+ fieldLabel: gettext('Subnet mask'),
vtype: 'IPAddress',
name: 'netmask',
validator: function(value) {
];
Ext.applyIf(me, {
- title: title,
url: url,
method: method,
items: {
var data = response.result.data;
if (data.type !== me.iftype) {
var msg = "Got unexpected device type";
- Ext.Msg.alert("Load failed", msg, function() {
+ Ext.Msg.alert(gettext('Error'), msg, function() {
me.close();
});
return;
}
me.setValues(data);
+ me.isValid(); // trigger validation
}
});
}
throw "no node name specified";
}
- var rstore = Ext.create('PVE.data.UpdateStore', {
- interval: 1000,
- storeid: 'pve-networks',
+ var store = Ext.create('Ext.data.Store', {
model: 'pve-networks',
proxy: {
type: 'pve',
]
});
- var store = Ext.create('PVE.data.DiffStore', { rstore: rstore });
-
- var view_changes = function() {
+ var reload = function() {
var changeitem = me.down('#changes');
PVE.Utils.API2Request({
- url: '/nodes/' + nodename + '/network_changes',
+ url: '/nodes/' + nodename + '/network',
failure: function(response, opts) {
changeitem.update('Error: ' + response.htmlStatus);
+ store.loadData({});
},
success: function(response, opts) {
var result = Ext.decode(response.responseText);
- var data = result.data;
- if (data === '') {
- data = "no changes";
+ store.loadData(result.data);
+ var changes = result.changes;
+ if (changes === undefined || changes === '') {
+ changes = gettext("No changes");
}
- changeitem.update("<pre>" + Ext.htmlEncode(data) + "</pre>");
+ changeitem.update("<pre>" + Ext.htmlEncode(changes) + "</pre>");
}
});
};
- var reload = function() {
- rstore.load();
- view_changes();
- };
-
var run_editor = function() {
var grid = me.down('gridpanel');
var sm = grid.getSelectionModel();
};
var edit_btn = new Ext.Button({
- text: 'Edit',
+ text: gettext('Edit'),
disabled: true,
handler: run_editor
});
var del_btn = new Ext.Button({
- text: 'Delete',
+ text: gettext('Remove'),
disabled: true,
handler: function(){
var grid = me.down('gridpanel');
del_btn.setDisabled(!rec);
};
- PVE.Utils.monStoreErrors(me, rstore);
+ PVE.Utils.monStoreErrors(me, store);
var render_ports = function(value, metaData, record) {
if (value === 'bridge') {
layout: 'border',
tbar: [
{
- text: 'Create',
+ text: gettext('Create'),
menu: new Ext.menu.Menu({
items: [
{
handler: function() {
var next;
for (next = 0; next <= 9999; next++) {
- if (!rstore.data.get('vmbr' + next.toString())) {
+ if (!store.data.get('vmbr' + next.toString())) {
break;
}
}
handler: function() {
var next;
for (next = 0; next <= 9999; next++) {
- if (!rstore.data.get('bond' + next.toString())) {
+ if (!store.data.get('bond' + next.toString())) {
break;
}
}
})
}, ' ',
{
- text: 'Revert changes',
+ text: gettext('Revert changes'),
handler: function() {
PVE.Utils.API2Request({
- url: '/nodes/' + nodename + '/network_changes',
+ url: '/nodes/' + nodename + '/network',
method: 'DELETE',
waitMsgTarget: me,
callback: function() {
reload();
},
failure: function(response, opts) {
- Ext.Msg.alert('Error', response.htmlStatus);
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
}
});
}
border: false,
columns: [
{
- header: 'Interface Name',
+ header: gettext('Name'),
width: 100,
sortable: true,
dataIndex: 'iface'
},
{
xtype: 'booleancolumn',
- header: 'Active',
+ header: gettext('Active'),
width: 80,
sortable: true,
dataIndex: 'active',
renderer: render_ports
},
{
- header: 'IP address',
+ header: gettext('IP address'),
sortable: true,
dataIndex: 'address'
},
{
- header: 'Subnet mask',
+ header: gettext('Subnet mask'),
sortable: true,
dataIndex: 'netmask'
},
autoScroll: true,
itemId: 'changes',
tbar: [
- 'Pending changes (please reboot to activate changes)'
+ gettext('Pending changes') + ' (' +
+ gettext('Please reboot to activate changes') + ')'
],
split: true,
bodyPadding: 5,
flex: 0.6,
- html: "no changes"
+ html: gettext("No changes")
}
],
listeners: {