diff --git a/bin/isrepo b/bin/isrepo
index c864932c07324c02e10bb6e0f3f9aeb9333d54e2..c654fd8923b3485ba2338511bbdd11338e57b1c1 100755
--- a/bin/isrepo
+++ b/bin/isrepo
@@ -26,27 +26,27 @@ def init(args):
     '''Create an empty fresh repo tree'''
     # call init from library
     try:
-        Repository.create(args.repo_image, args.repo_data, args.verbose)
+        Repository.create(args.repo, args.verbose)
     except Exception as e:
-        error("init failed: %s." % e)
+        raise Exception("init failed: %s" % e)
 
 def add(args):
     '''Add a package to repository'''
     try:
-        repo = Repository(args.repo_image, args.repo_data, args.verbose)
+        repo = Repository(args.repo, args.verbose)
         pkg = PackageImage(args.path, args.verbose)
         pkg.check_md5()
         repo.add(pkg)
     except Exception as e:
-        error("add failed: %s." % e)
+        raise Exception("add failed: %s" % e)
 
 def delete(args):
     '''Remove a package from repository'''
     try:
-        repo = Repository(args.repo_image, args.repo_data, args.verbose)
+        repo = Repository(args.repo, args.verbose)
         repo.delete(args.image_name, args.image_version)
     except Exception as e:
-        error("del failed: %s." % e)
+        raise Exception("del failed: %s" % e)
 
 # Top level argument parsing
 p_main = argparse.ArgumentParser()
@@ -60,10 +60,6 @@ p_main.add_argument("-c", "--config", dest="config", type=str, default=None,
                     help="config file path")
 p_main.add_argument("-r", "--repo-name", dest="repo_name", type=str, default=None,
                     help="repository name")
-p_main.add_argument("-I", "--repo-image", dest="repo_image", type=str,
-                    help="image repository path")
-p_main.add_argument("-D", "--repo-data", dest="repo_data", type=str,
-                    help="data repository path")
 subparsers = p_main.add_subparsers()
 # Init command parser
 p_init = subparsers.add_parser("init", help=init.__doc__.lower())
@@ -86,21 +82,16 @@ try:
     args = p_main.parse_args()
     # load config
     config = ConfigFile("isrepo", args.config)
-    # get config repository
-    c_repo = config.repo(args.repo_name)
-    # looks for image repository in config, if needed
-    if args.repo_image is None and c_repo is not None:
-        args.repo_image = c_repo[0]
-    # looks for data repository in config, if needed
-    if args.repo_data is None and c_repo is not None:
-        args.repo_data = c_repo[1]
-    # final check of existance
-    if args.repo_image is None:
-        raise Exception("image repository missing")
-    elif args.repo_data is None:
-        raise Exception("data repository missing")
-    debug("Image repo: %s" % args.repo_image)
-    debug("Data repo: %s" % args.repo_data)
+    # get config repositories
+    repos = config.repos
+    if len(repos) == 1:
+        args.repo = repos[repos.keys()[0]]
+    elif args.repo_name in repos.keys():
+        args.repo = repos[args.repo_name]
+    else:
+        raise Exception("No image repository found")
+    debug("Image repo: %s" % args.repo.image)
+    debug("Data repo: %s" % args.repo.data)
     args.func(args)
 except Exception as e:
     p_main.print_usage()
diff --git a/installsystems/config.py b/installsystems/config.py
index 55b7d94f6e1caae4bf8ba85f4a9ff60d0ee705d6..087cacfc667d3d8b96470e24b670c1a92189cf82 100644
--- a/installsystems/config.py
+++ b/installsystems/config.py
@@ -9,6 +9,7 @@ InstallSystems Configuration files class
 import os
 from ConfigParser import RawConfigParser
 from installsystems.printer import *
+from installsystems.repository import RepositoryConfig
 
 class ConfigFile(object):
     '''Configuration class'''
@@ -38,17 +39,19 @@ class ConfigFile(object):
             try:
                 cp = RawConfigParser()
                 cp.read(self.path)
+                # main configuration
                 if cp.has_section(self.prefix):
                     self._config = dict(cp.items(self.prefix))
                     cp.remove_section(self.prefix)
+                # each section is a repository
                 for rep in cp.sections():
-                    img = data = None
-                    if cp.has_option(rep, "image"):
-                        img = cp.get(rep, "image")
-                    if cp.has_option(rep, "data"):
-                        data = cp.get(rep, "data")
-                    self._repos[rep]= (img, data)
+                    # check if its a repo section
+                    if "image" not in cp.options(rep):
+                        continue
+                    # get all options in repo
+                    self._repos[rep] = RepositoryConfig(rep, **dict(cp.items(rep)))
             except Exception as e:
+                raise
                 raise Exception("Unable load file %s: %s" % (self.path, e))
         else:
             debug("No config file found")
@@ -87,18 +90,4 @@ class ConfigFile(object):
     @property
     def repos(self):
         '''Get a list of repository available'''
-        for r in self._repos:
-            yield (r, self._repos[r][0], self._repos[r][1])
-
-    def repo(self, name):
-        '''
-        Return a reposiory by its name
-        name can be None if there is only one repository
-        '''
-        if name is None and len(self._repos) == 1:
-            return self._repos[self._repos.keys()[0]]
-        elif name is not None:
-            if name in self._repos.keys():
-                return self._repos[name]
-        return None
-
+        return self._repos.copy()
diff --git a/installsystems/database.py b/installsystems/database.py
index e5a2092cff96da61ded526479f9273916f633b17..d0bfbf30c21bfecdf7809a4b54bfdad7b5fd8816 100644
--- a/installsystems/database.py
+++ b/installsystems/database.py
@@ -10,6 +10,7 @@ import json
 import os
 import shutil
 import tarfile
+import installsystems.tools as istools
 from installsystems.tarball import Tarball
 from installsystems.printer import *
 
@@ -50,7 +51,9 @@ class Database(object):
             newdb.add_str(name, package.jdescription(), tarfile.REGTYPE, 0444)
             db.close()
             newdb.close()
-            shutil.move(newdb_path, self.path)
+            # preserve permission and stats when moving
+            shutil.copystat(self.path, newdb_path)
+            os.rename(newdb_path, self.path)
         except Exception as e:
             raise Exception("Adding metadata fail: %s" % e)
 
@@ -67,7 +70,9 @@ class Database(object):
                     newdb.addfile(ti, db.extractfile(ti))
             db.close()
             newdb.close()
-            shutil.move(newdb_path, self.path)
+            # preserve permission and stats when moving
+            shutil.copystat(self.path, newdb_path)
+            os.rename(newdb_path, self.path)
         except Exception as e:
             raise Exception("Removing metadata fail: %s" % e)
 
diff --git a/installsystems/repository.py b/installsystems/repository.py
index 69d5d908202212960ad04e3b72b056f5c3b71eb6..16759299430b439318e911226c3d333f089359a1 100644
--- a/installsystems/repository.py
+++ b/installsystems/repository.py
@@ -9,6 +9,8 @@ Repository stuff
 import os
 import time
 import shutil
+import pwd
+import grp
 import installsystems
 import installsystems.tools as istools
 from installsystems.printer import *
@@ -19,40 +21,43 @@ from installsystems.database import Database
 class Repository(object):
     '''Repository class'''
 
-    last_name = "last"
-
-    def __init__(self, image_path, data_path, verbose=True):
-        self.image_path = os.path.abspath(image_path)
-        self.last_path = os.path.join(image_path, self.last_name)
-        self.data_path = os.path.abspath(data_path)
+    def __init__(self, config, verbose=True):
         self.verbose = verbose
-        self.db = Database(os.path.join(image_path, "db"), verbose=self.verbose)
+        self.config = config
+        self.db = Database(os.path.join(config.image, config.db), verbose=self.verbose)
+        self.last_path = os.path.join(config.image, config.last)
 
     @classmethod
-    def create(cls, image_path, data_path, verbose=True):
+    def create(cls, config, verbose=True):
         '''Create an empty base repository'''
         # create base directories
         arrow("Creating base directories", 1, verbose)
-        try:
-            for d in (image_path, data_path):
+        for d in (config.image, config.data):
+            try:
                 if os.path.exists(d):
-                    arrow("%s already exists" % os.path.relpath(d), 2, verbose)
+                    arrow("%s already exists" % d, 2, verbose)
                 else:
-                    os.mkdir(d)
-                    arrow("%s directory created" % os.path.relpath(d), 2, verbose)
-        except Exception as e:
-            raise Exception("Unable to create directory %s: %s" % (d, e))
+                    istools.mkdir(d, config.chown, config.chgroup, config.dchmod)
+                    arrow("%s directory created" % d, 2, verbose)
+            except Exception as e:
+                raise
+                raise Exception("Unable to create directory %s: %s" % (d, e))
         # create database
-        d = Database.create(os.path.join(image_path, "db"), verbose=verbose)
+        dbpath = os.path.join(config.image, "db")
+        d = Database.create(dbpath, verbose=verbose)
+        istools.chrights(dbpath, config.chown, config.chgroup, config.fchmod)
         # create last file
         arrow("Creating last file", 1, verbose)
-        self = cls(image_path, data_path, verbose)
+        self = cls(config, verbose)
         self.update_last()
+        return self
 
     def update_last(self):
         '''Update last file to current time'''
         try:
             open(self.last_path, "w").write("%s\n" % int(time.time()))
+            os.chown(self.last_path, self.config.chown, self.config.chgroup)
+            os.chmod(self.last_path, self.config.fchmod)
         except Exception as e:
             raise Exception("Update last file failed: %s" % e)
 
@@ -69,10 +74,12 @@ class Repository(object):
         # copy file to directory
         arrow("Adding file to directories", 1, self.verbose)
         arrow("Adding %s" % os.path.basename(package.path), 2, self.verbose)
-        shutil.copy(package.path, self.image_path)
+        istools.copy(package.path, self.config.image,
+                     self.config.chown, self.config.chgroup, self.config.fchmod)
         for db in package.databalls():
             arrow("Adding %s" % os.path.basename(db), 2, self.verbose)
-            shutil.copy(db, self.data_path)
+            istools.copy(db, self.config.data,
+                         self.config.chown, self.config.chgroup, self.config.fchmod)
         # add file to db
         self.db.add(package)
         # update last file
@@ -85,7 +92,7 @@ class Repository(object):
             error("Unable to find %s version %s in database" % (name, version))
         # removing script tarballs
         arrow("Removing script tarball", 1, self.verbose)
-        tpath = os.path.join(self.image_path, "%s-%s%s" % (name, version,
+        tpath = os.path.join(self.config.image, "%s-%s%s" % (name, version,
                                                            Image.image_extension))
         if os.path.exists(tpath):
             os.unlink(tpath)
@@ -93,7 +100,7 @@ class Repository(object):
         # removing data tarballs
         arrow("Removing data tarballs", 1, self.verbose)
         for tb in self.db.databalls(name, version):
-            tpath = os.path.join(self.data_path, tb)
+            tpath = os.path.join(self.config.data, tb)
             if os.path.exists(tpath):
                 os.unlink(tpath)
                 arrow("%s removed" % tb, 2, self.verbose)
@@ -104,6 +111,67 @@ class Repository(object):
         self.update_last()
 
 
+class RepositoryConfig(object):
+    '''Repository configuration container'''
+
+    def __init__(self, *args, **kwargs):
+        # set default value for arguments
+        self.name = args[0]
+        self.db = "db"
+        self.last = "last"
+        self.image = ""
+        self.data = ""
+        self.chown = os.getuid()
+        self.chgroup = os.getgid()
+        umask = os.umask(0)
+        os.umask(umask)
+        self.fchmod =  0666 & ~umask
+        self.dchmod =  0777 & ~umask
+        self.update(**kwargs)
+
+    def update(self, *args, **kwargs):
+        '''
+        Update attribute with checking value
+        All attribute must already exists
+        '''
+        # autoset parameter in cmdline
+        for k in kwargs:
+            if hasattr(self, k):
+                # attribute which are not in the following list cannot be loaded
+                # from configuration
+                try:
+                    # convert userid
+                    if k == "chown":
+                        if not k.isdigit():
+                            kwargs[k] = pwd.getpwnam(kwargs[k]).pw_uid
+                        setattr(self, k, int(kwargs[k]))
+                    # convert gid
+                    elif k == "chgroup":
+                        if not k.isdigit():
+                            kwargs[k] = grp.getgrnam(kwargs[k]).gr_gid
+                        setattr(self, k, int(kwargs[k]))
+                    # convert file mode
+                    elif k in ("fchmod", "dchmod"):
+                        setattr(self, k, int(kwargs[k], 8))
+                        # convert repo path
+                    elif k in ("image", "data"):
+                        setattr(self, k, istools.abspath(kwargs[k]))
+                    # else is string
+                    else:
+                        setattr(self, k, kwargs[k])
+                except Exception as e:
+                    warn("Unable to set config parameter %s in repository %s: %s" % (k, self.name, e))
+
+    def __eq__(self, other):
+        return vars(self) == vars(other)
+
+    def __ne__(self, other):
+        return not (self == other)
+
+    def __contains__(self, key):
+        return key in self.__dict__
+
+
 class RepositoryCache(object):
     '''Local repository cache class'''
 
@@ -124,9 +192,8 @@ class RepositoryCache(object):
     def register(self, iterepo):
         '''Register a repository to track'''
         for r in iterepo:
-            print r
-            self.repos[r[0]] = Repository(istools.complete_path(r[1]),
-                                          istools.complete_path(r[2]),
+            self.repos[r[0]] = Repository(istools.abspath(r[1]),
+                                          istools.abstpath(r[2]),
                                           verbose=self.verbose)
 
     def update(self):
@@ -138,9 +205,9 @@ class RepositoryCache(object):
                                                            self.last(r)))
             if self.repos[r].last() > self.last(r):
                 # copy last file
-                istools.cp(self.repos[r].last_path, os.path.join(self.last_path, r))
+                istools.copy(self.repos[r].last_path, os.path.join(self.last_path, r))
                 # copy db file
-                istools.cp(self.repos[r].db.path, os.path.join(self.db_path, r))
+                istools.copy(self.repos[r].db.path, os.path.join(self.db_path, r))
                 arrow("%s updated" % r, 2, self.verbose)
 
     def last(self, reponame):
@@ -162,7 +229,7 @@ class RepositoryCache(object):
         # get remote image
         remotepath = os.path.join(self.repos[reponame].image_path, filename)
         arrow("Copying from repository", 2, self.verbose)
-        istools.cp(remotepath, localpath)
+        istools.copy(remotepath, localpath)
         return localpath
 
     def find_image(self, name, version):
diff --git a/installsystems/tools.py b/installsystems/tools.py
index 717964c702dd36cd303a2422665be78f9600cc10..b4a084b58182429e1a121b3e8e514a595d626eac 100644
--- a/installsystems/tools.py
+++ b/installsystems/tools.py
@@ -16,18 +16,37 @@ def md5sum(path):
     m.update(open(path, "r").read())
     return m.hexdigest()
 
-def cp(source, destination):
+def copy(source, destination, uid=None, gid=None, mode=None):
     '''Copy a source to destination. Take care of path type'''
-    stype = get_path_type(source)
-    dtype = get_path_type(destination)
+    stype = pathtype(source)
+    dtype = pathtype(destination)
     if stype == dtype == "file":
         shutil.copy(source, destination)
     elif stype == "file" and dtype == "":
         raise NotImplementedError
     else:
         raise NotImplementedError
+    # setting destination file rights
+    if dtype == "file":
+        if os.path.isdir(destination):
+            destination = os.path.join(destination, os.path.basename(source))
+        chrights(destination, uid, gid, mode)
 
-def get_path_type(path):
+def mkdir(path, uid=None, gid=None, mode=None):
+    '''Create a directory and set rights'''
+    os.mkdir(path)
+    chrights(path, uid, gid, mode)
+
+def chrights(path, uid=None, gid=None, mode=None):
+    '''Set rights on a file'''
+    if uid is not None:
+        os.chown(path, uid, -1)
+    if gid is not None:
+        os.chown(path, -1, gid)
+    if mode is not None:
+        os.chmod(path, mode)
+
+def pathtype(path):
     '''Return path type. This is usefull to know what king of path is given'''
     from installsystems.image import Image
     if path.startswith("http://") or path.startswith("https://"):
@@ -40,9 +59,9 @@ def get_path_type(path):
         return "name"
     return None
 
-def complete_path(path):
-    '''Format a path to be complete'''
-    ptype = get_path_type(path)
+def abspath(path):
+    '''Format a path to be absolute'''
+    ptype = pathtype(path)
     if ptype in ("http", "ssh"):
         return path
     elif ptype == "file":