core updated.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Licensed under the GNU General Public License, version 3.
|
||||
# See the file http://www.gnu.org/licenses/gpl.txt
|
||||
|
||||
from pisi.actionsapi import shelltools
|
||||
from pisi.actionsapi import pisitools
|
||||
from pisi.actionsapi import get
|
||||
|
||||
def install():
|
||||
pisitools.dosed("bin/adduser.py", "plugdev", "removable")
|
||||
shelltools.system("./setup.py install %s" % get.installDIR())
|
||||
|
||||
# in new tarball remove
|
||||
shelltools.chmod(get.installDIR() + "/sbin/mudur_cgroupfs.py" , 0755)
|
||||
|
||||
pisitools.dodir("/etc/mudur/services/enabled")
|
||||
pisitools.dodir("/etc/mudur/services/disabled")
|
||||
pisitools.dodir("/etc/mudur/services/conditional")
|
||||
@@ -0,0 +1,492 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
FSTAB = '/etc/fstab'
|
||||
|
||||
"""
|
||||
Quick list is used for improving efficiency of the script.
|
||||
Stores device names and uuids pairs for partitions so prevents multiple
|
||||
communication with subprocesses.
|
||||
"""
|
||||
quickList = {}
|
||||
|
||||
FAIL_FSTAB = {
|
||||
"en": "Unable to read '%s'.",
|
||||
"tr": "'%s' okunamadı.",
|
||||
"fr": "Impossible de lire '%s' .",
|
||||
"es": "No posible leer '%s'.",
|
||||
"de": "'%s' konnte nicht gelesen werden.",
|
||||
"nl": "Kan '%s' niet lezen.",
|
||||
}
|
||||
|
||||
FAIL_PATH = {
|
||||
"en": "'%s' is not a valid mount point.",
|
||||
"tr": "'%s' geçerli bir bağlama noktası değil.",
|
||||
"fr": "'%s' n'est pas un point de montage valide.",
|
||||
"es": "'%s' no es un punto de montaje válido.",
|
||||
"de": "'%s' ist kein gültiger Mount-Punkt.",
|
||||
"nl": "'%s' is geen geldig aankoppelpunt.",
|
||||
}
|
||||
|
||||
FAIL_PATH_ALREADY_EXIST = {
|
||||
"en": "'%s' is already being used by an entry.",
|
||||
"tr": "'%s' zaten bir kayıt tarafından kullanılıyor.",
|
||||
"fr": "'%s' est déjà utilisé par une entrée.",
|
||||
"es": "Ya '%s' siendo utilizado por una entrada.",
|
||||
"de": "'%s' wird bereits durch einen Eintrag verwendet.",
|
||||
"nl": "'%s' bruges allerede af en post.",
|
||||
}
|
||||
|
||||
FAIL_ENTRY = {
|
||||
"en": "Device '%s' not found in entry list.",
|
||||
"tr": "'%s' aygıtı listede bulunamadı.",
|
||||
"fr": "Le matériel '%s' n'a pas été trouvé dans la liste.",
|
||||
"es": "Dispositivo '%s' no encontrado en lista de entrada.",
|
||||
"de": "Gerät '%s' ist nicht in der Liste eingetragen.",
|
||||
"nl": "Apparaat '%s' is niet in invoerlijst gevonden.",
|
||||
}
|
||||
|
||||
FAIL_ROOT = {
|
||||
"en": "'%s' is mounted to root directory, operation cancelled.",
|
||||
"tr": "'%s' diski kök dizine bağlı, işlem iptal edildi.",
|
||||
"fr": "'%s' est monté sur le répertoire racine, opération annulée.",
|
||||
"es": "'%s' está montado com root, operación cancelada.",
|
||||
"de": "'%s' ist als Root gemounted, Vorgang abgebrochen.",
|
||||
"nl": "'%s' is in root-map aangekoppeld, bewerking geannuleerd.",
|
||||
}
|
||||
|
||||
FAIL_MOUNTED = {
|
||||
"en": "'%s' is mounted to another directory, operation cancelled.",
|
||||
"tr": "'%s' başka bir dizine bağlı, işlem iptal edildi.",
|
||||
"fr": "'%s' est monté sur un autre répertoire, opération annulée.",
|
||||
"es": "'%s' está montado en otro directorio, operación cancelada.",
|
||||
"de": "'%s' ist schon auf einem anderen Mount-Punkt gemounted, Vorgang abgebrochen.",
|
||||
"nl": "'%s' is in een andere map aangekoppeld, bewerking geannuleerd.",
|
||||
}
|
||||
|
||||
FAIL_OPERATION = {
|
||||
"en": "Operation failed:\n\n %s",
|
||||
"tr": "İşlem başarısız:\n\n %s",
|
||||
"fr": "L'opération a échoué : \n\n %s",
|
||||
"es": "Operación fallada:\n\n %s",
|
||||
"de": "Vorgang fehlerhaft:\n\n %s",
|
||||
"nl": "Mislukte bewerking:\n\n %s",
|
||||
}
|
||||
|
||||
class DMException(Exception):
|
||||
pass
|
||||
|
||||
def parseFstab(fstab):
|
||||
if not os.access(fstab, os.R_OK):
|
||||
raise DMException, _(FAIL_FSTAB) % fstab
|
||||
entries = []
|
||||
for line in open(fstab):
|
||||
line = line.strip()
|
||||
# Check len(line) for empty lines.
|
||||
if line.startswith('#') or len(line) == 0:
|
||||
continue
|
||||
line = line.replace('\t', ' ').split()
|
||||
# Replace UUID value with device name after reading it from fstab
|
||||
if line[0].startswith('UUID='):
|
||||
line[0] = getPartitionNameByUUID(line[0])
|
||||
entries.append(line)
|
||||
elif line[0].startswith('LABEL='):
|
||||
line[0] = getDeviceByLabel(line[0].replace('LABEL=', ''))
|
||||
entries.append(line)
|
||||
elif line[0].startswith('/dev/'):
|
||||
entries.append(line)
|
||||
return entries
|
||||
|
||||
def createPath(device, path):
|
||||
real_path = path
|
||||
if not os.path.exists(path) and os.path.exists(os.path.dirname(path)):
|
||||
# Mount point does not exist, but parent directory does.
|
||||
path = os.path.dirname(path)
|
||||
if not os.path.ismount(path) and not os.path.islink(path) and os.path.isdir(path):
|
||||
os.mkdir(real_path, 0755)
|
||||
return True
|
||||
else:
|
||||
if os.path.ismount(path):
|
||||
# Path is already mounted, allow user to use that mount point if it's already mounted
|
||||
for _device, _path in getMounted():
|
||||
if device == _device and _path == path:
|
||||
return True
|
||||
else:
|
||||
if not os.path.islink(path) and os.path.isdir(path) and os.listdir(path) == []:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getMounted():
|
||||
parts = []
|
||||
for line in open('/proc/mounts'):
|
||||
if line.startswith('/dev/'):
|
||||
device, path, other = line.split(" ", 2)
|
||||
parts.append((device, path, ))
|
||||
return parts
|
||||
|
||||
def getFSType(device):
|
||||
if device.startswith('UUID='):
|
||||
device = getPartitionNameByUUID(device)
|
||||
cmd = "/sbin/blkid -s TYPE -o value %s" % device
|
||||
proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
|
||||
return proc.communicate()[0].strip()
|
||||
|
||||
def getUUID(part):
|
||||
"""
|
||||
Finds UUID for the given partition.
|
||||
"""
|
||||
global quickList
|
||||
if len(quickList) == 0:
|
||||
fillQuickList()
|
||||
return quickList[part]
|
||||
|
||||
def getPartitionNameByUUID(part):
|
||||
"""
|
||||
Finds name of the partition for the given UUId.
|
||||
"""
|
||||
global quickList
|
||||
part = part.replace('UUID=', '')
|
||||
if len(quickList) == 0:
|
||||
fillQuickList()
|
||||
for devName, uuid in quickList.items():
|
||||
if uuid == part:
|
||||
return devName
|
||||
return ''
|
||||
|
||||
def fillQuickList():
|
||||
"""
|
||||
Fills the quick list.
|
||||
"""
|
||||
global quickList
|
||||
cmd = "/sbin/blkid"
|
||||
proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
|
||||
for line in proc.stdout:
|
||||
line = line.replace(':', '').strip()
|
||||
propList = line.split()
|
||||
devName = label = uuid = fsType = ''
|
||||
devName = propList[0]
|
||||
for property in propList:
|
||||
if property.startswith('UUID'):
|
||||
uuid = property.replace('UUID=', '').replace('"', '')
|
||||
quickList[devName] = uuid
|
||||
|
||||
def runCommand(cmd):
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
err = proc.communicate()[1].strip()
|
||||
if len(err):
|
||||
fail(_(FAIL_OPERATION) % err)
|
||||
|
||||
# Disk.Manager methods
|
||||
|
||||
def isMounted(device):
|
||||
"""
|
||||
Searches the given partition in mounted devices. If partition is
|
||||
mounted, returns mount point else returns none.
|
||||
"""
|
||||
for _device, _path in getMounted():
|
||||
if device == _device:
|
||||
return _path
|
||||
return ''
|
||||
|
||||
def getDevices():
|
||||
from pardus.diskutils import EDD
|
||||
return EDD().blockDevices()
|
||||
|
||||
def getDeviceByLabel(label):
|
||||
root = '/dev/disk/by-label'
|
||||
path = os.path.join(root, label)
|
||||
if os.access(path, os.R_OK):
|
||||
return os.path.realpath(os.path.join(root, os.readlink(path)))
|
||||
else:
|
||||
return ''
|
||||
|
||||
def getDeviceParts(device):
|
||||
if not os.path.exists(device):
|
||||
return []
|
||||
parts = []
|
||||
for part in glob.glob("%s*" % device):
|
||||
if not part == device and not getFSType(part) == "":
|
||||
parts.append(part)
|
||||
return parts
|
||||
|
||||
def getLabel(device):
|
||||
"""
|
||||
Finds label for the given partition.
|
||||
"""
|
||||
cmd = "/sbin/blkid -s LABEL -o value %s" % device
|
||||
proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
|
||||
return proc.communicate()[0].strip()
|
||||
|
||||
def getPath(device):
|
||||
"""
|
||||
Gets partition name and determine a path for that partition.
|
||||
"""
|
||||
# If there is a entry record for this partition in fstab
|
||||
# use path in there.
|
||||
if device in listEntries():
|
||||
path_, fsType_, options_ = getEntry(device)
|
||||
return path_
|
||||
path = '/media/'
|
||||
label = getLabel(device)
|
||||
# There may be partitions without a label
|
||||
if not label:
|
||||
if not os.path.exists(path+'disk'):
|
||||
path = path+'disk'
|
||||
elif not os.path.ismount(path+'disk'):
|
||||
path = path+'disk'
|
||||
else:
|
||||
for i in range(1, len(getMounted())):
|
||||
if not os.path.exists(path+'disk-'+str(i)):
|
||||
path = path+'disk-'+str(i)
|
||||
break
|
||||
elif not os.path.ismount(path+'disk-'+str(i)):
|
||||
path = path+'disk-'+str(i)
|
||||
break
|
||||
# Labels may be same
|
||||
else:
|
||||
if not os.path.exists(path+label):
|
||||
path = path+label
|
||||
elif not os.path.ismount(path+label):
|
||||
path = path+label
|
||||
else:
|
||||
for i in range(1, len(getMounted())):
|
||||
if not os.path.exists(path+label+'-'+str(i)):
|
||||
path = path+label+'-'+str(i)
|
||||
break
|
||||
elif not os.path.ismount(path+label+'-'+str(i)):
|
||||
path = path+label+'-'+str(i)
|
||||
break
|
||||
return path
|
||||
|
||||
def mount(device, path):
|
||||
if not path:
|
||||
path = getPath(device)
|
||||
if not createPath(device, path):
|
||||
# Can't create new path
|
||||
fail(_(FAIL_PATH) % path)
|
||||
elif device in [x[0] for x in getMounted()]:
|
||||
# Device is mounted
|
||||
fail(_(FAIL_MOUNTED) % device)
|
||||
runCommand(['/bin/mount', device, path])
|
||||
|
||||
def umount(device):
|
||||
for dev, path in getMounted():
|
||||
if dev == device and path == "/":
|
||||
fail(_(FAIL_ROOT) % device)
|
||||
runCommand(['/bin/umount', device])
|
||||
|
||||
def listEntries():
|
||||
try:
|
||||
devices = [x[0] for x in parseFstab(FSTAB)]
|
||||
return devices
|
||||
except DMException:
|
||||
return []
|
||||
|
||||
def listPaths():
|
||||
"""
|
||||
Return paths of the entries in fstab.
|
||||
"""
|
||||
try:
|
||||
paths = [x[1] for x in parseFstab(FSTAB)]
|
||||
return paths
|
||||
except DMException:
|
||||
return []
|
||||
|
||||
def isLabelRecord(device):
|
||||
for line in open(FSTAB):
|
||||
line = line.strip().replace('\t', ' ').split()
|
||||
if line:
|
||||
if line[0] == 'LABEL=' + getLabel(device):
|
||||
return True
|
||||
|
||||
def addEntry(device, path, fsType, options):
|
||||
path_own = False
|
||||
if device in listEntries():
|
||||
old_path, old_fsType, old_options = getEntry(device)
|
||||
# Do not change root
|
||||
if old_path == "/" and not old_path == path:
|
||||
fail(_(FAIL_ROOT) % device)
|
||||
# Who has that mount point? me?
|
||||
if old_path == path:
|
||||
path_own = True
|
||||
else:
|
||||
# If the path value already exist in fstab, cut the operation
|
||||
if path in listPaths():
|
||||
fail(_(FAIL_PATH_ALREADY_EXIST) % path)
|
||||
old_path = None
|
||||
if not createPath(device, path):
|
||||
# Can't create new path
|
||||
fail(_(FAIL_PATH) % path)
|
||||
#elif device in [x[0] for x in getMounted()]:
|
||||
# Device is mounted
|
||||
#fail(_(FAIL_MOUNTED) % device)
|
||||
partText = ''
|
||||
# Before removing the entry check if it is a label record or uuid record
|
||||
# Remove previous one to prevent duplicates
|
||||
if old_path:
|
||||
if isLabelRecord(device):
|
||||
partText = 'LABEL='+getLabel(device)
|
||||
else:
|
||||
partText = 'UUID='+getUUID(device)
|
||||
else:
|
||||
partText = 'UUID='+getUUID(device)
|
||||
# Add new entry
|
||||
_options = []
|
||||
for key, value in options.iteritems():
|
||||
if value:
|
||||
_options.append('%s=%s' % (key, value))
|
||||
else:
|
||||
_options.append(key)
|
||||
if not file(FSTAB).read()[-1] == '\n':
|
||||
file(FSTAB, 'a').write('\n')
|
||||
_options = ','.join(_options)
|
||||
|
||||
addit = True
|
||||
# If the partition is not already mounted the given path and,
|
||||
# if the partition is not mounted anywhere, try to create a path
|
||||
# and mount there.
|
||||
if not path_own:
|
||||
if not createPath(device, path):
|
||||
addit = False
|
||||
# Can't create new path
|
||||
fail(_(FAIL_PATH) % path)
|
||||
if not device in [x[0] for x in getMounted()]:
|
||||
# Mount device
|
||||
try:
|
||||
mount(device, path)
|
||||
except:
|
||||
addit = False
|
||||
raise
|
||||
if addit:
|
||||
# try to remove old entry before
|
||||
if old_path:
|
||||
removeEntry(device, silent=True)
|
||||
if _options:
|
||||
file(FSTAB, 'a').write('%s %s %s %s 0 0\n' % (partText, path, fsType, _options))
|
||||
else:
|
||||
file(FSTAB, 'a').write('%s %s %s defaults 0 0\n' % (partText, path, fsType))
|
||||
# Notify clients
|
||||
notify("Disk.Manager", "changed", ())
|
||||
|
||||
def getEntry(device):
|
||||
entries = parseFstab(FSTAB)
|
||||
for entry in entries:
|
||||
if entry[0] == device:
|
||||
_path, _fsType, _options, _dump, _pass = entry[1:]
|
||||
options = {}
|
||||
for part in _options.split(','):
|
||||
if "=" in part:
|
||||
key, value = part.split('=', 1)
|
||||
options[key] = value
|
||||
else:
|
||||
options[part] = ""
|
||||
return _path, _fsType, options
|
||||
fail(_(FAIL_ENTRY) % device)
|
||||
|
||||
def removeEntry(device, silent=False):
|
||||
if isMounted(device) == '/':
|
||||
fail(_(FAIL_ROOT) % device)
|
||||
if device not in listEntries():
|
||||
return
|
||||
newlines = []
|
||||
for line in open(FSTAB):
|
||||
line = line.strip()
|
||||
if not len(line) == 0 and not (line.replace('\t', ' ').split()[0] == 'UUID='+getUUID(device) or line.replace('\t', ' ').split()[0] == 'LABEL='+getLabel(device) or line.replace('\t', ' ').split()[0] == device):
|
||||
newlines.append(line)
|
||||
file(FSTAB, 'w').write('\n'.join(newlines))
|
||||
if not file(FSTAB).read()[-1] == '\n':
|
||||
file(FSTAB, 'a').write('\n')
|
||||
# Notify clients
|
||||
if not silent:
|
||||
notify("Disk.Manager", "changed", ())
|
||||
|
||||
|
||||
import errno
|
||||
from time import sleep
|
||||
from fcntl import ioctl
|
||||
|
||||
# Path to sync executable
|
||||
PATH_SYNC = '/bin/sync'
|
||||
|
||||
# Emulate required asm-generic/ioctl.h macros
|
||||
_IOC_NRBITS = 8
|
||||
_IOC_TYPEBITS = 8
|
||||
_IOC_SIZEBITS = 14
|
||||
_IOC_DIRBITS = 2
|
||||
|
||||
_IOC_NRMASK = ((1 << _IOC_NRBITS) - 1)
|
||||
_IOC_TYPEMASK = ((1 << _IOC_TYPEBITS) - 1)
|
||||
_IOC_SIZEMASK = ((1 << _IOC_SIZEBITS) - 1)
|
||||
_IOC_DIRMASK = ((1 << _IOC_DIRBITS) - 1)
|
||||
|
||||
_IOC_NRSHIFT = 0
|
||||
_IOC_TYPESHIFT = (_IOC_NRSHIFT + _IOC_NRBITS)
|
||||
_IOC_SIZESHIFT = (_IOC_TYPESHIFT + _IOC_TYPEBITS)
|
||||
_IOC_DIRSHIFT = (_IOC_SIZESHIFT + _IOC_SIZEBITS)
|
||||
|
||||
# Direction bits.
|
||||
_IOC_NONE = 0
|
||||
_IOC_WRITE = 1
|
||||
_IOC_READ = 2
|
||||
|
||||
def _IOC(dir,type,nr,size):
|
||||
return (((dir) << _IOC_DIRSHIFT) | \
|
||||
(type << _IOC_TYPESHIFT) | \
|
||||
((nr) << _IOC_NRSHIFT) | \
|
||||
((size) << _IOC_SIZESHIFT))
|
||||
|
||||
def _IO(type, nr):
|
||||
"""Note: type is specified in hex and nr in decimal."""
|
||||
return _IOC(_IOC_NONE,(type),(nr),0)
|
||||
|
||||
def BLKRRPART():
|
||||
"""Returns ioctl number for re-reading partition table."""
|
||||
# Kernels >2.6.17 have BLKRRPART defined in include/linux/fs.h.
|
||||
return _IO(0x12, 95)
|
||||
# -------------------------------------------
|
||||
|
||||
def refreshPartitionTable(device):
|
||||
"""Re-Read partition table on device."""
|
||||
|
||||
try:
|
||||
fd = os.open(device, os.O_RDONLY)
|
||||
except EnvironmentError, (error, strerror):
|
||||
print 'Could not open device %s. Reason: %s.'%(device, strerror)
|
||||
sys.exit(-1)
|
||||
|
||||
# Sync and wait for Sync to complete
|
||||
os.system(PATH_SYNC)
|
||||
sleep(2)
|
||||
|
||||
# Call required ioctl to re-read partition table
|
||||
try:
|
||||
ioctl(fd, BLKRRPART())
|
||||
except EnvironmentError, (error, message):
|
||||
# Attempt ioctl call twice in case an older kernel (1.2.x) is being used
|
||||
os.system(PATH_SYNC)
|
||||
sleep(2)
|
||||
|
||||
try:
|
||||
ioctl(fd, BLKRRPART())
|
||||
except EnvironmentError, (error, strerror):
|
||||
print 'IOCTL Error: %s for device %s.'%(strerror, device)
|
||||
sys.exit(-1)
|
||||
|
||||
print 'Successfully re-read partition table on device %s.'%(device)
|
||||
# Sync file buffers
|
||||
os.fsync(fd)
|
||||
os.close(fd)
|
||||
|
||||
# Final sync
|
||||
print "Syncing %s ... " % (device),
|
||||
os.system(PATH_SYNC)
|
||||
sleep(4) # for sync()
|
||||
print "Done."
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from comar.service import *
|
||||
import time
|
||||
|
||||
from pardus.fstabutils import Fstab
|
||||
|
||||
serviceType = "local"
|
||||
serviceDefault = "off"
|
||||
serviceDesc = _({"en": "Remote Filesystem Mounter",
|
||||
"tr": "Uzak Dosyasistemi Bağlayıcı"})
|
||||
|
||||
DATAFILE = "/var/run/netfs.status"
|
||||
|
||||
MSG_NM_NOT_RUNNING = _({"en": "NetworkManager service is not running",
|
||||
"tr": "NetworkManager hizmeti çalışmıyor",
|
||||
})
|
||||
|
||||
@synchronized
|
||||
def start():
|
||||
# Mount all remote filesystems
|
||||
if run("/usr/bin/nm-online -q -t 10") != 0:
|
||||
# NM is not running
|
||||
fail(MSG_NM_NOT_RUNNING)
|
||||
|
||||
fstab = Fstab()
|
||||
for entry in fstab.get_entries():
|
||||
if entry.is_remote_mount():
|
||||
if entry.is_nfs():
|
||||
# Start rpcbind if fs is nfs|nfs4
|
||||
startDependencies("rpcbind")
|
||||
# Mount it
|
||||
entry.mount()
|
||||
|
||||
@synchronized
|
||||
def stop():
|
||||
# Unmount all remote filesystems
|
||||
fstab = Fstab()
|
||||
for entry in fstab.get_entries():
|
||||
if entry.is_remote_mount():
|
||||
entry.unmount()
|
||||
|
||||
def status():
|
||||
fstab = Fstab()
|
||||
for entry in fstab.get_entries():
|
||||
if entry.is_remote_mount() and entry.is_mounted():
|
||||
return True
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
def postInstall(fromVersion, fromRelease, toVersion, toRelease):
|
||||
shutil.copyfile("/etc/fstab", "/etc/fstab.bak")
|
||||
new = []
|
||||
for line in [line.strip() for line in open("/etc/fstab.bak")]:
|
||||
if re.search("\s+\/(run|dev\/shm)\s+", line): continue
|
||||
new.append(line)
|
||||
new.append("tmpfs /run tmpfs nodev,nosuid,size=10%,mode=755 0 0\n")
|
||||
with open("/etc/fstab", "w") as f: f.write("\n".join(new))
|
||||
|
||||
# add disks into fstab
|
||||
# os.system("/sbin/update-fstab")
|
||||
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import piksemel
|
||||
import imp
|
||||
|
||||
def doenv(filetag):
|
||||
for item in filetag:
|
||||
path = item.getTagData("Path")
|
||||
if path.startswith("etc/env.d"):
|
||||
updenv = imp.load_source("updenv", "/sbin/update-environment")
|
||||
updenv.update_environment("/")
|
||||
return
|
||||
|
||||
def setupPackage(metapath, filepath):
|
||||
doc = piksemel.parse(filepath)
|
||||
doenv(doc.tags("File"))
|
||||
|
||||
def cleanupPackage(metapath, filepath):
|
||||
pass
|
||||
|
||||
def postCleanupPackage(metapath, filepath):
|
||||
doc = piksemel.parse(filepath)
|
||||
doenv(doc.tags("File"))
|
||||
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pardus.fileutils import FileLock
|
||||
from pardus.localedata import languages as LANGUAGES
|
||||
|
||||
# Mudur configuration file
|
||||
|
||||
CONF = "/etc/conf.d/mudur"
|
||||
TTY_DEFAULT = 6
|
||||
|
||||
# Required utils
|
||||
|
||||
def getConf(key, default=None):
|
||||
lock = FileLock(CONF)
|
||||
lock.lock(shared=True)
|
||||
value = default
|
||||
for line in file(CONF):
|
||||
line = line.strip()
|
||||
try:
|
||||
_key, _value = line.split("=", 1)
|
||||
except ValueError:
|
||||
continue
|
||||
_key = _key.strip()
|
||||
if key == _key:
|
||||
value = _value.strip()
|
||||
if value.startswith('"') or value.startswith("'"):
|
||||
value = value[1:-1]
|
||||
break
|
||||
lock.unlock()
|
||||
return value
|
||||
|
||||
def setConf(key, value=None):
|
||||
lock = FileLock(CONF)
|
||||
lock.lock(shared=False)
|
||||
data = file(CONF).read()
|
||||
lines = data.split("\n")
|
||||
for index, line in enumerate(lines):
|
||||
try:
|
||||
_key, _value = line.split("=", 1)
|
||||
except ValueError:
|
||||
continue
|
||||
_key = _key.strip()
|
||||
if key == _key or (_key.startswith("#") and _key[1:].strip() == key):
|
||||
if value:
|
||||
lines[index] = "%s = '%s'" % (key, value)
|
||||
elif not line.startswith("#"):
|
||||
lines[index] = "# %s" % line
|
||||
file(CONF, "w").write("\n".join(lines))
|
||||
lock.unlock()
|
||||
|
||||
# System.Settings methods
|
||||
|
||||
def listLanguages():
|
||||
languages = []
|
||||
for code, info in LANGUAGES.iteritems():
|
||||
languages.append((code, str(info.name)))
|
||||
return languages
|
||||
|
||||
def getLanguage():
|
||||
return getConf("language", "en")
|
||||
|
||||
def setLanguage(lang):
|
||||
if not len(lang):
|
||||
lang = None
|
||||
setConf("language", lang)
|
||||
|
||||
|
||||
def listKeymaps(language):
|
||||
keymaps = []
|
||||
if language and language in LANGUAGES:
|
||||
for keymap in LANGUAGES[language].keymaps:
|
||||
keymaps.append((keymap.console_layout, str(keymap.name)))
|
||||
else:
|
||||
for language in LANGUAGES:
|
||||
for keymap in LANGUAGES[language].keymaps:
|
||||
keymaps.append((keymap.console_layout, str(keymap.name)))
|
||||
return keymaps
|
||||
|
||||
def getKeymap():
|
||||
return getConf("keymap", "us")
|
||||
|
||||
def setKeymap(keymap):
|
||||
if not len(keymap):
|
||||
keymap = None
|
||||
setConf("keymap", keymap)
|
||||
|
||||
|
||||
def getHeadStart():
|
||||
return getConf("head_start")
|
||||
|
||||
def setHeadStart(package):
|
||||
if not len(package):
|
||||
package = None
|
||||
setConf("head_start", package)
|
||||
|
||||
|
||||
def getClock():
|
||||
is_utc = getConf("clock", "local") == "UTC"
|
||||
adjust = getConf("clock_adjust", "no") == "yes"
|
||||
return is_utc, adjust
|
||||
|
||||
def setClock(is_utc, adjust):
|
||||
if is_utc:
|
||||
setConf("clock", "UTC")
|
||||
else:
|
||||
setConf("clock", "local")
|
||||
if adjust:
|
||||
setConf("clock_adjust", "yes")
|
||||
else:
|
||||
setConf("clock_adjust", "no")
|
||||
|
||||
|
||||
def getTTYs():
|
||||
count = getConf("tty_number", TTY_DEFAULT)
|
||||
try:
|
||||
return int(count)
|
||||
except (ValueError, TypeError):
|
||||
return TypeError
|
||||
|
||||
def setTTYs(count):
|
||||
setConf("tty_number", count)
|
||||
@@ -0,0 +1,43 @@
|
||||
fix issue #562
|
||||
https://github.com/pisilinux/PisiLinux/issues/562
|
||||
|
||||
--- bin/mudur.py.orig 2015-05-11 20:46:23.509195049 +0200
|
||||
+++ bin/mudur.py 2015-05-11 22:26:06.000000000 +0200
|
||||
@@ -1406,7 +1406,7 @@
|
||||
UI.info(_("Creating tmpfiles"))
|
||||
if not os.path.isdir("/run/tmpfiles.d"): create_directory("/run/tmpfiles.d")
|
||||
run("/usr/bin/kmod", "static-nodes", "--format=tmpfiles", "--output=/run/tmpfiles.d/kmod.conf")
|
||||
- out = [line for line in capture("/sbin/mudur_tmpfiles.py")[0].split("\n") if line.strip()]
|
||||
+ out = [line for line in capture("/sbin/mudur_tmpfiles.py", "--boot")[0].split("\n") if line.strip()]
|
||||
if out: LOGGER.log("Errors during tmpfiles creation.\n\t%s" % "\n\t".join(out))
|
||||
run("mount", "-t", "tmpfs", "tmpfs", "/dev/shm")
|
||||
|
||||
--- bin/mudur_tmpfiles.py.orig 2015-05-11 20:46:23.519200049 +0200
|
||||
+++ bin/mudur_tmpfiles.py 2015-05-11 20:40:04.000000000 +0200
|
||||
@@ -80,6 +80,7 @@
|
||||
|
||||
if __name__ == "__main__":
|
||||
if ("-h" or "--help") in sys.argv: usage()
|
||||
+ boot = True if "--boot" in sys.argv else False
|
||||
|
||||
config_files = {}
|
||||
errors = []
|
||||
@@ -90,7 +91,7 @@
|
||||
except KeyError:
|
||||
config_files[head] = [tail]
|
||||
|
||||
- if sys.argv[1:]:
|
||||
+ if sys.argv[1:] and not boot:
|
||||
for arg in sys.argv[1:]:
|
||||
(head, tail) = os.path.split(arg)
|
||||
if not tail.endswith(".conf"): errors.append("%s is not .conf file" % tail)
|
||||
@@ -130,6 +131,9 @@
|
||||
if i == "-": fields[n] = ""
|
||||
if not fields[3]: fields[3] = "root"
|
||||
if not fields[4]: fields[4] = "root"
|
||||
+ if fields[0].endswith("!"):
|
||||
+ if not boot: continue
|
||||
+ else: fields[0] = fields[0].replace("!", "")
|
||||
if not fields[0] in ["c", "d", "D", "f", "F", "L", "w"]: errors.append("%s - wrong type in file: %s" % (fields[0], os.path.join(d, f)))
|
||||
elif fields[0] == "L":
|
||||
if not fields[6]: errors.append("No arg for type 'L' specified in file: %s" % os.path.join(d, f))
|
||||
@@ -0,0 +1,115 @@
|
||||
diff -Nuar mudur-4.4.0.orig/bin/mudur_cgroupfs.py mudur-4.4.0/bin/mudur_cgroupfs.py
|
||||
--- mudur-4.4.0.orig/bin/mudur_cgroupfs.py 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ mudur-4.4.0/bin/mudur_cgroupfs.py 2015-05-13 22:58:43.264005210 +0300
|
||||
@@ -0,0 +1,81 @@
|
||||
+# -*- coding : utf-8 -*-
|
||||
+import os, sys
|
||||
+
|
||||
+def mountpoint(path):
|
||||
+ status = os.system("mountpoint -q %s" % path)
|
||||
+ if status == 0:
|
||||
+ return True
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+class Controller:
|
||||
+ def __init__(self, subsysname, hierarchy, num_cgroups, enabled ):
|
||||
+ self.subsysname = subsysname
|
||||
+ self.hierarchy = hierarchy
|
||||
+ self.num_cgroups = num_cgroups
|
||||
+ self.enabled = enabled
|
||||
+
|
||||
+ def mount(self):
|
||||
+ if self.enabled == 1:
|
||||
+ os.chdir("/sys/fs/cgroup")
|
||||
+ if mountpoint(self.subsysname) == False:
|
||||
+ s = self.subsysname
|
||||
+ status = os.system("mkdir -p %s; mount -n -t cgroup -o %s cgroup %s" % (s, s,s))
|
||||
+ if status == 0:
|
||||
+ return True
|
||||
+ else:
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+class Cgroupfs:
|
||||
+ def __init__(self):
|
||||
+ self.controllers = {}
|
||||
+ if self.check_fstab == True:
|
||||
+ print("cgroupfs in fstab, exiting.")
|
||||
+ sys.exit(-1)
|
||||
+
|
||||
+ if self.kernel_support() == False:
|
||||
+ print("No kernel support for cgroupfs, exiting.")
|
||||
+ sys.exit(-2)
|
||||
+
|
||||
+ if self.check_sysfs() == False:
|
||||
+ print("/sys/fs/cgroups directory not found, exiting")
|
||||
+ sys.exit(-3)
|
||||
+
|
||||
+ self.mount_cgroup()
|
||||
+ self.find_controllers()
|
||||
+ for cname, c in self.controllers.items():
|
||||
+ c.mount()
|
||||
+
|
||||
+ def check_fstab(self):
|
||||
+ found = False
|
||||
+ for line in open("/etc/fstab").readlines():
|
||||
+ if line[0] == "#":
|
||||
+ continue
|
||||
+ else:
|
||||
+ if line.find("cgroup"):
|
||||
+ found = True
|
||||
+ return found
|
||||
+
|
||||
+ def kernel_support(self):
|
||||
+ return os.path.isfile("/proc/cgroups")
|
||||
+
|
||||
+ def check_sysfs(self):
|
||||
+ return os.path.isdir("/sys/fs/cgroup")
|
||||
+
|
||||
+ def mount_cgroup(self):
|
||||
+ if mountpoint("/sys/fs/cgroup") == False:
|
||||
+ cmd = " mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup"
|
||||
+ return os.system(cmd)
|
||||
+
|
||||
+ def find_controllers(self):
|
||||
+ for line in open("/proc/cgroups").readlines():
|
||||
+ line = line.strip()
|
||||
+ if line[0] == "#":
|
||||
+ continue
|
||||
+ else:
|
||||
+ subsysname, hierarchy, num_cgroups, enabled = line.split()
|
||||
+ enb = int(enabled)
|
||||
+ hie = int(hierarchy)
|
||||
+ numc= int(num_cgroups)
|
||||
+ self.controllers[subsysname] = Controller(subsysname, hie, numc, enb)
|
||||
diff -Nuar mudur-4.4.0.orig/bin/mudur.py mudur-4.4.0/bin/mudur.py
|
||||
--- mudur-4.4.0.orig/bin/mudur.py 2015-05-13 22:57:33.660007190 +0300
|
||||
+++ mudur-4.4.0/bin/mudur.py 2015-05-13 22:59:17.161004246 +0300
|
||||
@@ -22,6 +22,7 @@
|
||||
import signal
|
||||
import gettext
|
||||
import subprocess
|
||||
+from mudur_cgroupfs import Cgroupfs
|
||||
|
||||
########
|
||||
# i18n #
|
||||
@@ -1025,6 +1026,7 @@
|
||||
break
|
||||
df.close()
|
||||
run_full("/bin/mount", "-t", "tmpfs", "-o", "nodev,nosuid,size=10%,mode=755", "tmpfs", "/run")
|
||||
+ c = Cgroupfs()
|
||||
|
||||
def mount_remote_filesystems():
|
||||
"""Mounts remote filesystems."""
|
||||
diff -Nuar mudur-4.4.0.orig/setup.py mudur-4.4.0/setup.py
|
||||
--- mudur-4.4.0.orig/setup.py 2014-03-07 23:15:31.000000000 +0200
|
||||
+++ mudur-4.4.0/setup.py 2015-05-13 23:05:23.092993840 +0300
|
||||
@@ -77,6 +77,7 @@
|
||||
|
||||
install_file("bin/mudur.py", prefix, "sbin/mudur.py")
|
||||
install_file("bin/mudur_tmpfiles.py", prefix, "sbin/mudur_tmpfiles.py")
|
||||
+ install_file("bin/mudur_cgroupfs.py", prefix, "sbin/mudur_cgroupfs.py")
|
||||
install_file("bin/update-environment.py", prefix, "sbin/update-environment")
|
||||
install_file("bin/update-fstab.py", prefix, "sbin/update-fstab")
|
||||
install_file("bin/compat.py", prefix, "etc/init.d/compat.py")
|
||||
@@ -0,0 +1,11 @@
|
||||
--- bin/mudur.py~ 2014-06-14 14:28:45.136961885 +0200
|
||||
+++ bin/mudur.py 2014-06-14 14:29:12.000000000 +0200
|
||||
@@ -1406,7 +1406,7 @@
|
||||
UI.info(_("Creating tmpfiles"))
|
||||
if not os.path.isdir("/run/tmpfiles.d"): create_directory("/run/tmpfiles.d")
|
||||
run("/usr/bin/kmod", "static-nodes", "--format=tmpfiles", "--output=/run/tmpfiles.d/kmod.conf")
|
||||
- out = capture("/sbin/mudur_tmpfiles.py")[0].strip().split("\n")
|
||||
+ out = [line for line in capture("/sbin/mudur_tmpfiles.py")[0].split("\n") if line.strip()]
|
||||
if out: LOGGER.log("Errors during tmpfiles creation.\n\t%s" % "\n\t".join(out))
|
||||
run("mount", "-t", "tmpfs", "tmpfs", "/dev/shm")
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
--- bin/mudur_tmpfiles.py~ 2014-05-16 03:56:41.000000000 +0200
|
||||
+++ bin/mudur_tmpfiles.py 2014-06-11 21:54:58.333421994 +0200
|
||||
@@ -37,6 +37,10 @@
|
||||
open(path, mode).write(content)
|
||||
|
||||
def create(type, path, mode, uid, gid, age, arg):
|
||||
+ if type == "d" and \
|
||||
+ os.path.isdir(path) and \
|
||||
+ (not uid == os.stat(path).st_uid or not gid == os.stat(path).st_gid):
|
||||
+ type = "D"
|
||||
if type == "L":
|
||||
if not os.path.islink(path): os.symlink(arg, path)
|
||||
return
|
||||
@@ -0,0 +1,10 @@
|
||||
--- bin/mudur_tmpfiles.py~ 2014-08-03 17:48:07.461463934 +0200
|
||||
+++ bin/mudur_tmpfiles.py 2014-08-03 17:49:06.951461761 +0200
|
||||
@@ -63,6 +63,7 @@
|
||||
os.makedirs(os.path.dirname(path))
|
||||
os.chown(os.path.dirname(path), uid, gid)
|
||||
write_file(path, arg, mode = "a" if type == "f" else "w")
|
||||
+ os.chmod(path, mode)
|
||||
os.chown(path, uid, gid)
|
||||
|
||||
USAGE = """\
|
||||
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!DOCTYPE PISI SYSTEM "http://www.pisilinux.org/projeler/pisi/pisi-spec.dtd">
|
||||
<PISI>
|
||||
<Source>
|
||||
<Name>mudur</Name>
|
||||
<Homepage>http://www.pisilinux.org</Homepage>
|
||||
<Packager>
|
||||
<Name>PisiLinux Community</Name>
|
||||
<Email>admins@pisilinux.org</Email>
|
||||
</Packager>
|
||||
<License>GPLv2</License>
|
||||
<IsA>app:console</IsA>
|
||||
<Summary>Pisi Linux boot and initialization system</Summary>
|
||||
<Description>mudur handles mounting of the filesystems, loading of the device drivers, starting of the system services, and other jobs during the Pisi Linux boot and shutdown sequences.</Description>
|
||||
<Archive sha1sum="42c9163b5fe3d9682caa20f639fbec1d0be784cd" type="tarxz">http://source.pisilinux.org/1.0/mudur-4.4.0.tar.xz</Archive>
|
||||
<Patches>
|
||||
<Patch>set_file_mode.patch</Patch>
|
||||
<Patch>no_err-no_msg.patch</Patch>
|
||||
<Patch>recreate_dir_if_new_uid_or_gid.patch</Patch>
|
||||
<Patch>boot_option.patch</Patch>
|
||||
<Patch level="1">mount_cgroupfs.patch</Patch>
|
||||
</Patches>
|
||||
</Source>
|
||||
|
||||
<Package>
|
||||
<Name>mudur</Name>
|
||||
<RuntimeDependencies>
|
||||
<Dependency release="7">kbd</Dependency>
|
||||
<Dependency>bash</Dependency>
|
||||
<Dependency>dbus</Dependency>
|
||||
<Dependency>kmod</Dependency>
|
||||
<Dependency>eudev</Dependency>
|
||||
<Dependency>comar</Dependency>
|
||||
<Dependency>procps</Dependency>
|
||||
<Dependency>python</Dependency>
|
||||
<Dependency>rsyslog</Dependency>
|
||||
<Dependency>sysvinit</Dependency>
|
||||
<Dependency>coreutils</Dependency>
|
||||
<Dependency>e2fsprogs</Dependency>
|
||||
<Dependency>net-tools</Dependency>
|
||||
<Dependency>baselayout</Dependency>
|
||||
<Dependency>util-linux</Dependency>
|
||||
<Dependency>wireless-tools</Dependency>
|
||||
<Dependency>pisilinux-python</Dependency>
|
||||
</RuntimeDependencies>
|
||||
<Files>
|
||||
<Path fileType="config">/etc/conf.d</Path>
|
||||
<Path fileType="data">/etc/mudur/services</Path>
|
||||
<Path fileType="executable">/etc/init.d</Path>
|
||||
<Path fileType="executable">/sbin</Path>
|
||||
<Path fileType="executable">/bin</Path>
|
||||
<Path fileType="localedata">/usr/share/locale</Path>
|
||||
</Files>
|
||||
<Provides>
|
||||
<COMAR script="pakhandler.py">System.PackageHandler</COMAR>
|
||||
<COMAR script="netfs.py" name="netfs">System.Service</COMAR>
|
||||
<COMAR script="package.py">System.Package</COMAR>
|
||||
<COMAR script="system.py">System.Settings</COMAR>
|
||||
<COMAR script="disk.py">Disk.Manager</COMAR>
|
||||
</Provides>
|
||||
</Package>
|
||||
|
||||
<History>
|
||||
<Update release="17">
|
||||
<Date>2015-05-13</Date>
|
||||
<Version>4.4.0</Version>
|
||||
<Comment>fix issue #562, rebuild, depend new kbd and eudev, mount cgroups</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="16">
|
||||
<Date>2014-08-03</Date>
|
||||
<Version>4.4.0</Version>
|
||||
<Comment>Set mode for newly created files.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="15">
|
||||
<Date>2014-06-11</Date>
|
||||
<Version>4.4.0</Version>
|
||||
<Comment>Recreate dir if uid or gid has been changed.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="14">
|
||||
<Date>2014-05-11</Date>
|
||||
<Version>4.4.0</Version>
|
||||
<Comment>Release bump.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="13">
|
||||
<Date>2014-05-06</Date>
|
||||
<Version>4.4.0</Version>
|
||||
<Comment>No error line in log file when tmpfiles created successfully.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="12">
|
||||
<Date>2014-03-16</Date>
|
||||
<Version>4.4.0</Version>
|
||||
<Comment>Remove /dev/shm line from /etc/fstab.
|
||||
Add mounting /run to fstab for fresh installed system.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="11">
|
||||
<Date>2014-03-07</Date>
|
||||
<Version>4.4.0</Version>
|
||||
<Comment>Version bump.</Comment>
|
||||
<Name>Serdar Soytetir</Name>
|
||||
<Email>kaptan@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="10">
|
||||
<Date>2014-02-13</Date>
|
||||
<Version>4.3.1</Version>
|
||||
<Comment>Mount or remount tmpfs at /run.
|
||||
Starts with kmod.conf and baselayout.conf at the begining.
|
||||
Strip mudur_tmpfiles output.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="9">
|
||||
<Date>2014-02-10</Date>
|
||||
<Version>4.3.1</Version>
|
||||
<Comment>Try to fix D-Bus start issue using cleanup_run.</Comment>
|
||||
<Name>Serdar Soytetir</Name>
|
||||
<Email>kaptan@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="8">
|
||||
<Date>2014-01-21</Date>
|
||||
<Version>4.3.1</Version>
|
||||
<Comment>Version bump.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="7">
|
||||
<Date>2014-01-19</Date>
|
||||
<Version>4.3.0</Version>
|
||||
<Comment>Version bump.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="6">
|
||||
<Date>2013-10-28</Date>
|
||||
<Version>4.2.0</Version>
|
||||
<Comment>rebuild</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="5">
|
||||
<Date>2013-09-10</Date>
|
||||
<Version>4.2.0</Version>
|
||||
<Comment>Run udev after remount rootfs.
|
||||
Fix /run/shm mode.</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="4">
|
||||
<Date>2013-09-05</Date>
|
||||
<Version>4.2.0</Version>
|
||||
<Comment>Add missing method to pakhandler.py</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="3">
|
||||
<Date>2013-06-26</Date>
|
||||
<Version>4.2.0</Version>
|
||||
<Comment>Fix migration from /var/run to /run</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="2">
|
||||
<Date>2013-05-15</Date>
|
||||
<Version>4.2.0</Version>
|
||||
<Comment>Fix default groups for /sbin/useradd</Comment>
|
||||
<Name>Marcin Bojara</Name>
|
||||
<Email>marcin@pisilinux.org</Email>
|
||||
</Update>
|
||||
<Update release="1">
|
||||
<Date>2012-12-02</Date>
|
||||
<Version>4.2.0</Version>
|
||||
<Comment>First release</Comment>
|
||||
<Name>Serdar Soytetir</Name>
|
||||
<Email>kaptan@pisilinux.org</Email>
|
||||
</Update>
|
||||
</History>
|
||||
</PISI>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" ?>
|
||||
<PISI>
|
||||
<Source>
|
||||
<Name>mudur</Name>
|
||||
<Summary xml:lang="tr">Pisi Linux açılış sistemi</Summary>
|
||||
<Description xml:lang="tr">Pisi Linux açılış ve kapanışı sırasında, dosya sistemlerinin bağlanması, donanım sürücülerinin yüklenmesi, servislerin başlatılması gibi işleri yürütür.</Description>
|
||||
<Description xml:lang="fr">Gère le montage de systèmes de fichier, le chargement de pilotes de périphérique, le démarrage des services système et d'autres tâches pendant les séquences de démarrage et d'arrêt de Pisi Linux.</Description>
|
||||
</Source>
|
||||
</PISI>
|
||||
Reference in New Issue
Block a user