Index: umc/setup.xml
===================================================================
--- umc/setup.xml (Revision 43637)
+++ umc/setup.xml (Arbeitskopie)
@@ -20,7 +20,6 @@
-
Index: umc/python/setup/__init__.py
===================================================================
--- umc/python/setup/__init__.py (Revision 43637)
+++ umc/python/setup/__init__.py (Arbeitskopie)
@@ -65,7 +65,6 @@
RE_IPV4 = re.compile(r'^interfaces/(([^/_]+)(_[0-9])?)/(address|netmask)$')
RE_IPV6_DEFAULT = re.compile(r'^interfaces/([^/]+)/ipv6/default/(prefix|address)$')
-RE_SPACE = re.compile(r'\s+')
RE_SSL = re.compile(r'^ssl/.*')
class Instance(umcm.Base):
@@ -79,6 +78,7 @@
os.umask( 0022 )
def init( self ):
+ locale.setlocale( locale.LC_ALL, str( self.locale ) )
util.installer_i18n.set_language( str( self.locale ) )
os.environ[ 'LC_ALL' ] = str( self.locale )
@@ -344,8 +344,8 @@
_check('server/role', lambda x: not(orgValues.get('joined')) or (orgValues.get('server/role') == values.get('server/role')), _('The system role may not change on a system that has already joined to domain.'))
# basis
- components = RE_SPACE.split(values.get('components', ''))
- packages = set(reduce(lambda x, y: x + y, [ i.split(':') for i in components ]))
+ components = values.get('components', [])
+ packages = set(reduce(lambda x, y: x + y, [ comp.get('defaultpackages', []) for comp in components if comp.get('is_installed')]))
_check('hostname', util.is_hostname, _('The hostname is not a valid fully qualified domain name in lowercase (e.g. host.example.com).'))
_check('hostname', lambda x: len(x) <= 13, _('A valid NetBIOS name can not be longer than 13 characters. If Samba is installed, the hostname should be shortened.'), critical=('univention-samba' in packages or 'univention-samba4' in packages))
@@ -522,10 +522,3 @@
"interface" and optionally the key "timeout" (in seconds).'''
return util.dhclient(interface, timeout)
-
- @simple_response
- def software_components(self, role=None):
- '''Return a list of all available software packages. Entries have the properties
- "id", "label", and "packages" which is an array of the Debian package names.'''
- return [ { 'id': i['id'], 'label': i['Name'], 'packages': i['Packages'] }
- for i in util.get_components(role=role) ]
Index: umc/python/setup/util.py
===================================================================
--- umc/python/setup/util.py (Revision 43637)
+++ umc/python/setup/util.py (Arbeitskopie)
@@ -40,22 +40,15 @@
import univention.config_registry
import time
import re
-import sys
-import apt
import psutil
import csv
-import imp
import os.path
-from univention.lib.i18n import Translation
from univention.management.console.log import MODULE
-installer_i18n = Translation( 'installer', localedir = '/lib/univention-installer/locale' )
+from univention.management.console.modules.appcenter.app_center import Application
+from univention.lib.package_manager import PackageManager
-if not '/lib/univention-installer/' in sys.path:
- sys.path.append('/lib/univention-installer/')
-import package_list
-
ucr=univention.config_registry.ConfigRegistry()
ucr.load()
@@ -73,6 +66,13 @@
RE_IPV4_TYPE = re.compile('interfaces/[^/]*/type')
RE_LOCALE = re.compile(r'([^.@ ]+).*')
+read_only_package_manager = PackageManager(
+ info_handler=MODULE.process,
+ step_handler=None,
+ error_handler=MODULE.warn,
+ lock=False,
+)
+
# list of all needed UCR variables
UCR_VARIABLES = [
# common
@@ -123,8 +123,8 @@
else:
values['timezone']=''
- # get installed components
- values['components'] = ' '.join([icomp['id'] for icomp in get_installed_components()])
+ # get components
+ values['components'] = get_components()
return values
@@ -160,20 +160,18 @@
# add lists with all packages that should be removed/installed on the system
if 'components' in newValues:
- regSpaces = re.compile(r'\s+')
- selectedComponents = set(regSpaces.split(newValues.get('components', '')))
- currentComponents = set([icomp['id'] for icomp in get_installed_components()])
- allComponents = set([ icomp['id'] for icomp in get_components() ])
+ components_selected = dict([comp['id'], comp.get('is_installed', False)] for comp in newValues['components'])
+ all_components = get_components()
# get all packages that shall be removed
- removeComponents = list(allComponents & (currentComponents - selectedComponents))
- newValues['packages_remove'] = ' '.join([ i.replace(':', ' ') for i in removeComponents ])
+ remove_apps = [ app for app in all_components if app['is_installed'] and not components_selected.get(app['id'], False) ]
+ newValues['apps_remove'] = ' '.join([app['id'] for app in remove_apps])
- allComponents = set([ icomp['id'] for icomp in get_components(role=role) ])
+ all_components = get_components(role=role)
# get all packages that shall be installed
- installComponents = list(allComponents & (selectedComponents - currentComponents))
- newValues['packages_install'] = ' '.join([ i.replace(':', ' ') for i in installComponents ])
+ install_apps = [ app for app in all_components if not app['is_installed'] and components_selected.get(app['id'], False) ]
+ newValues['apps_install'] = ' '.join([app['id'] for app in install_apps])
# if 'locale' in newValues:
# # js returns locale as list
@@ -235,11 +233,12 @@
# fractions of setup scripts
FRACTIONS = {
- '10_basis/12domainname' : 5,
- '10_basis/14ldap_basis' : 10,
- '30_net/10interfaces' : 5,
- '30_net/11ipv6interfaces' : 5,
- '50_software/10software' : 50,
+ '10_basis/12domainname' : 5,
+ '10_basis/14ldap_basis' : 10,
+ '30_net/10interfaces' : 5,
+ '30_net/11ipv6interfaces' : 5,
+ '50_software/10software' : 5, # deprecated, probably not used
+ '50_software/20apps' : 50,
}
# current status
@@ -552,49 +551,18 @@
return dhcp_dict
def get_components(role=None):
- '''Returns a list of components that may be installed on the current system.'''
+ '''Returns a list of all components.'''
- # get all package sets that are available for the current system role
- if not role:
- role = ucr.get('server/role')
+ components = []
+ read_only_package_manager.reopen_cache()
+ Application._get_category_translations(fake=True)
+ for app in Application.all(force_reread=True, only_local=True):
+ if 'UCS components' in app.get('categories'):
+ if role and app.get('serverrole') and role not in app.get('serverrole'):
+ continue
+ components.append(app.to_dict(read_only_package_manager))
+ return components
- # reload for correct locale
- imp.reload(package_list)
- pkglist = [ jpackage for icategory in package_list.PackageList
- for jpackage in icategory['Packages']
- if 'all' in jpackage['Possible'] or role in jpackage['Possible'] ]
-
- # filter whitelisted packages
- whitelist = ucr.get('system/setup/packages/whitelist')
- if whitelist:
- whitelist = whitelist.split(' ')
- pkglist = [ipkg for ipkg in pkglist if all(jpkg in whitelist for jpkg in ipkg['Packages'])]
-
- # filter blacklisted packages
- blacklist = ucr.get('system/setup/packages/blacklist')
- if blacklist:
- blacklist = blacklist.split(' ')
- pkglist = [ipkg for ipkg in pkglist if not any(jpkg in blacklist for jpkg in ipkg['Packages'])]
-
- # generate a unique ID for each component
- for ipkg in pkglist:
- ipkg['id'] = ':'.join(ipkg['Packages'])
- ipkg[ 'Description' ] = installer_i18n.translate( ipkg[ 'Description' ] )
- ipkg[ 'Name' ] = installer_i18n.translate( ipkg[ 'Name' ] )
-
- return pkglist
-
-def get_installed_packages():
- '''Returns a list of all installed packages on the system.'''
- cache = apt.Cache()
- return [ p.name for p in cache if p.is_installed ]
-
-def get_installed_components():
- '''Returns a list of components that are currently fully installed on the system.'''
- allPackages = set(get_installed_packages())
- allComponents = get_components()
- return [ icomp for icomp in allComponents if not len(set(icomp['Packages']) - allPackages) ]
-
# from univention-installer/installer/modules/70_net.py
def is_proxy(proxy):
if proxy and proxy != 'http://' and proxy != 'https://':
Index: umc/js/setup/SoftwarePage.js
===================================================================
--- umc/js/setup/SoftwarePage.js (Revision 43637)
+++ umc/js/setup/SoftwarePage.js (Arbeitskopie)
@@ -33,180 +33,77 @@
"dojo/_base/lang",
"dojo/_base/array",
"umc/tools",
- "umc/widgets/Form",
- "umc/widgets/Page",
- "umc/widgets/MultiSelect",
+ "umc/widgets/StandbyMixin",
+ "umc/modules/appcenter/AppCenterPage",
"umc/i18n!umc/modules/setup"
-], function(declare, lang, array, tools, Form, Page, MultiSelect, _) {
+], function(declare, lang, array, tools, StandbyMixin, AppCenterPage, _) {
- return declare("umc.modules.setup.SoftwarePage", [ Page ], {
- // summary:
- // This class renderes a detail page containing subtabs and form elements
- // in order to edit UDM objects.
+ return declare("umc.modules.setup.SoftwarePage", [ AppCenterPage, StandbyMixin ], {
+ liveSearch: false,
+ addMissingAppButton: false,
+ standbyDuringUpdateApplications: false,
- // system-setup-boot
- wizard_mode: false,
+ title: _('Software'),
+ headerText: _('Software settings'),
+ helpText: _('Via the software settings, particular software components may be installed or removed.'),
- // __systemsetup__ user is logged in at local firefox session
- local_mode: false,
-
- umcpCommand: tools.umcpCommand,
-
- // internal reference to the formular containing all form widgets of an UDM object
- _form: null,
-
- _orgComponents: undefined,
-
- _noteShowed: false,
-
- postMixInProperties: function() {
- this.inherited(arguments);
-
- this.title = _('Software');
- this.headerText = _('Software settings');
- this.helpText = _('Via the software settings, particular software components may be installed or removed.');
+ getAppCenterSeen: function() {
+ return true;
},
- buildRendering: function() {
- this.inherited(arguments);
-
- var widgets = [{
- type: MultiSelect,
- name: 'components',
- label: _('Installed software components'),
- umcpCommand: this.umcpCommand,
- dynamicValues: 'setup/software/components',
- dynamicOptions: {},
- sortDynamicValues: false,
- style: 'width: 500px;',
- height: '200px'
- }];
-
- var layout = [{
- label: _('Installation of software components'),
- layout: ['components']
- }];
-
- this._form = new Form({
- widgets: widgets,
- layout: layout,
- scrollable: true
- });
- this._form.on('submit', lang.hitch(this, 'onSave'));
-
- this.addChild(this._form);
-
- // show notes when samba 3/4 is selected
- this.own(this._form.getWidget('components').watch('value', lang.hitch(this, function(name, oldVal, newVal) {
- array.forEach(['samba', 'samba4'], function(ikey) {
- var r = new RegExp('univention-' + ikey + '\\b');
- if (array.some(this._getInstalledComponents(), function(icomponent) { return (r.test(icomponent)); }, this)) {
- this._showNote(ikey);
- }
- }, this);
- })));
-
- // show notes for changes in the software settings
- this.own(this._form.getWidget('components').watch('value', lang.hitch(this, function() {
- this._showNote('software');
- })));
-
- // remember which notes have already been shown
- this._noteShowed = { };
- this._myNotes = {
- samba: _('It is not possible to mix NT and Active Directory compatible domaincontroller. Make sure the existing UCS domain is NT-compatible (Samba 3).'),
- samba4: _('It is not possible to mix NT and Active Directory compatible domaincontroller. Make sure the existing UCS domain is Active Directory-compatible (Samba 4).'),
- software: _('Installing or removing software components may result in restarting or stopping services. This can have severe side-effects when the system is in productive use at the moment.')
- };
+ showDetails: function(app) {
+ // do not show anything. toggle installed flag
+ app.is_installed = !app.is_installed;
+ this._grid.store.notify(app, app.id);
+ // TODO: show warning? notes?
},
- _showNote: function(key) {
- if (!(key in this._noteShowed) || !this._form.getWidget('components').focused) {
- // make sure key exists
- return;
- }
-
- if (!this._noteShowed[key]) {
- this._noteShowed[key] = true;
- this.addNote(this._myNotes[key]);
- }
- },
-
setValues: function(vals) {
- // set dynamicOption to get list of components corresponding to selected system role
- this._form.getWidget('components').set('dynamicOptions', { role: vals['server/role'] });
-
- // get a dict of all installed components and initialise component list
- var components = (vals.components || '').split(/\s+/);
- this._form.getWidget('components').setInitialValue(components, true);
-
+ this._components = lang.clone(vals.components);
if (this._orgComponents === undefined) {
- this._orgComponents = {};
- array.forEach(components, function(icomponent) {
- if(icomponent !== "") {
- this._orgComponents[icomponent] = true;
- }
- }, this);
+ this._orgComponents = lang.clone(this._components);
}
+ this.updateApplications();
+ this.set('appQuery', {
+ serverrole: {
+ test: function(serverrole) {
+ return serverrole.length === 0 || array.indexOf(serverrole, vals['server/role']) >= 0;
+ }
+ }
+ });
+ },
- // handling of notes
- this._noteShowed = { };
- var role = vals['server/role'];
- if (role == 'domaincontroller_backup' || role == 'domaincontroller_slave') {
- // only show samba notes on backup/slave
- this._noteShowed.samba = false;
- this._noteShowed.samba4 = false;
- }
- // show note when changing software only on a joined system in productive mode
- this._noteShowed.software = this.wizard_mode;
- this.clearNotes();
+ getApplications: function() {
+ return this._components || [];
},
getValues: function() {
return {
- components: this._form.getWidget('components').get('value').join(' ')
+ components: this.getApplications()
};
},
- _getComponents: function() {
- // return a dict of currently selected components
- var components = {};
- array.forEach(this._form.get('value').components, function(icomp) {
- components[icomp] = true;
- });
- return components;
- },
-
_getRemovedComponents: function() {
// if a previously installed component has been deselected
// -> uninstall all its packages
- var components = [];
- var selectedComponents = this._getComponents();
- tools.forIn(this._orgComponents, function(icomponent) {
- if (!(icomponent in selectedComponents)) {
- components.push(icomponent);
- }
- });
- return components;
+ return array.filter(this._orgComponents, lang.hitch(this, function(component) {
+ return component.is_installed && !this._grid.store.get(component.id).is_installed;
+ }));
},
_getInstalledComponents: function() {
// if a previously not/partly installed component has been selected
// -> install all its packages
- var components = [];
- tools.forIn(this._getComponents(), function(icomponent) {
- if (!(icomponent in this._orgComponents)) {
- components.push(icomponent);
- }
- }, this);
- return components;
+ return array.filter(this._orgComponents, lang.hitch(this, function(component) {
+ return !component.is_installed && this._grid.store.get(component.id).is_installed;
+ }));
},
getSummary: function() {
// a list of all components with their labels
var allComponents = {};
- array.forEach(this._form.getWidget('components').getAllItems(), function(iitem) {
- allComponents[iitem.id] = iitem.label;
+ array.forEach(this._grid.store.data, function(component) {
+ allComponents[component.id] = component.name;
});
// get changed components
@@ -218,7 +115,7 @@
var components = [];
if (installComponents.length) {
components = array.map(installComponents, function(icomponent) {
- return allComponents[icomponent];
+ return allComponents[icomponent.id];
});
result.push({
variables: ['components'],
@@ -228,7 +125,7 @@
}
if (removeComponents.length) {
components = array.map(removeComponents, function(icomponent) {
- return allComponents[icomponent];
+ return allComponents[icomponent.id];
});
result.push({
variables: ['components'],
Index: umc/js/setup.js
===================================================================
--- umc/js/setup.js (Revision 43637)
+++ umc/js/setup.js (Arbeitskopie)
@@ -120,7 +120,7 @@
},
renderPages: function(ucr, values) {
- this._progressBar = new ProgressBar();
+ this._progressBar = new ProgressBar({});
this.own(this._progressBar);
this.standby(true);
Index: usr/lib/univention-system-setup/scripts/50_software/20apps
===================================================================
--- usr/lib/univention-system-setup/scripts/50_software/20apps (Revision 0)
+++ usr/lib/univention-system-setup/scripts/50_software/20apps (Revision 0)
@@ -0,0 +1,94 @@
+#!/usr/bin/python2.6
+# -*- coding: utf-8 -*-
+#
+# Univention System Setup
+# apps installation script
+#
+# Copyright 2013 Univention GmbH
+#
+# http://www.univention.de/
+#
+# All rights reserved.
+#
+# The source code of this program is made available
+# under the terms of the GNU Affero General Public License version 3
+# (GNU AGPL V3) as published by the Free Software Foundation.
+#
+# Binary versions of this program provided by Univention to you as
+# well as other copyrighted, protected or trademarked materials like
+# Logos, graphics, fonts, specific documentations and configurations,
+# cryptographic keys etc. are subject to a license agreement between
+# you and Univention and not subject to the GNU AGPL V3.
+#
+# In the case you use this program under the terms of the GNU AGPL V3,
+# the program is provided in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public
+# License with the Debian GNU/Linux or Univention distribution in file
+# /usr/share/common-licenses/AGPL-3; if not, see
+# .
+import os.path
+
+from univention.management.console.modules.setup.setup_script import AptScript, main, _
+from univention.management.console.modules.appcenter.app_center import Application
+from univention.updater import UniventionUpdater
+from univention.management.console.modules.appcenter.util import ComponentManager
+from univention.config_registry import ConfigRegistry
+
+class AppScript(AptScript):
+ name = _('Configuring software components')
+ script_name = os.path.abspath(__file__)
+ brutal_apt_options = False
+
+ def up(self):
+ super(AppScript, self).up()
+
+ # get this scripts configuration options
+ self.apps_remove = self.get_profile_var_list('apps_remove')
+ self.apps_install = self.get_profile_var_list('apps_install')
+ ucr = ConfigRegistry()
+ uu = UniventionUpdater(False)
+ self.component_manager = ComponentManager(ucr, uu)
+
+ def inner_run(self):
+ if not (self.apps_remove or self.apps_install):
+ # nothing to do. dont autoremove either
+ return True
+ # +1 for update
+ ntasks = len(self.apps_remove) + len(self.apps_install) + 1
+ self.steps(ntasks * 100)
+
+ # apt-get update
+ if self.update():
+ self.finish_task('Update')
+ else:
+ return False
+ base_package = self.get_package_for_role(self.current_server_role)
+ if base_package is None:
+ return False
+ else:
+ self.set_always_install(base_package)
+
+ Application._get_category_translations(fake=True)
+ Application.all(only_local=True)
+ for app_id in self.apps_remove:
+ # apt-get remove *app.defaultpackages
+ app = Application.find(app_id)
+ app.uninstall(self.package_manager, self.component_manager)
+ self.finish_task(app.name)
+
+ for app_id in self.apps_install:
+ # apt-get install *app.defaultpackages
+ app = Application.find(app_id)
+ app.install(self.package_manager, self.component_manager)
+ self.finish_task(app.name)
+
+ return True
+
+if __name__ == '__main__':
+ script = AppScript()
+ main(script)
+
Index: debian/control
===================================================================
--- debian/control (Revision 43637)
+++ debian/control (Arbeitskopie)
@@ -22,6 +22,7 @@
shell-univention-lib,
python-univention-lib (>= 1.0.25-1),
console-tools,
+ univention-management-console-module-appcenter,
shell-univention-lib (>= 3.0.1-1),
python-univention-lib (>= 3.0.1-1)
Recommends: univention-management-console-module-setup