[TIC-CORE] support recommends tag 19/119019/1
authorChulwoo Shin <cw1.shin@samsung.com>
Wed, 15 Mar 2017 07:00:41 +0000 (16:00 +0900)
committerChulwoo Shin <cw1.shin@samsung.com>
Wed, 15 Mar 2017 07:00:41 +0000 (16:00 +0900)
- support dedendency analysis for recommends tag
- support tic-core configurations

Change-Id: I7c9a7579a04726536721c9e4832773b27c609bef
Signed-off-by: Chulwoo Shin <cw1.shin@samsung.com>
tic/command.py
tic/config.py [new file with mode: 0644]
tic/dependency.py
tic/parser/recipe_parser.py
tic/parser/repo_parser.py
tic/repo.py
tic/server/tic_server.py
tic/utils/error.py
tic/utils/grabber.py
tic/utils/rpmmisc.py
tools/tic-core

index 661466c..40a156b 100644 (file)
@@ -34,10 +34,11 @@ from tic.pykickstarter import KSoption, kswriter
 from tic.utils import process
 from tic.utils import misc
 from tic.utils import file
+from tic.config import configmgr
 
-DEFAULT_CACHEDIR='/var/tmp/tic-core'
-DEFAULT_ANALYSIS_CACHEDIR='/var/tmp/tic-core/analysis'
-DEFAULT_KICKSTARTDIR='/var/tmp/tic-core/kickstart'
+DEFAULT_CACHEDIR=configmgr.setting['tempdir']
+DEFAULT_ANALYSISDIR=os.path.join(DEFAULT_CACHEDIR, 'analysis')
+DEFAULT_KICKSTARTDIR=os.path.join(DEFAULT_CACHEDIR, 'kickstart')
 
 def analyze(repo_list, recipe_list=None):
     logger = logging.getLogger(__name__)
@@ -67,7 +68,7 @@ def analyze(repo_list, recipe_list=None):
     for repo in repoinfo:
         checksum_list.append(repo['checksum'])
     all_checksum = hashlib.sha256('_'.join(checksum_list)).hexdigest()
-    analysis_file=os.path.join(DEFAULT_ANALYSIS_CACHEDIR, all_checksum, 'analysis.json')
+    analysis_file=os.path.join(DEFAULT_ANALYSISDIR, all_checksum, 'analysis.json')
     pkg_group=None
     if os.path.exists(analysis_file):
         pkg_group=file.read_json(analysis_file)
diff --git a/tic/config.py b/tic/config.py
new file mode 100644 (file)
index 0000000..0c6eb09
--- /dev/null
@@ -0,0 +1,76 @@
+
+import os
+import ConfigParser
+
+DEFAULT_MSG_CONF = "/etc/tic-core/message.conf"
+DEFAULT_CONF = "/etc/tic-core/config.conf"
+
+class ConfigMgr(object):
+    DEFAULT_MESSAGE = {'message': {
+                        'repo_not_found': "The repository url cannot be found (%s)",
+                        'xml_parse_error': "There was a problem parsing the %s, please check the file (%s)",
+                        'yaml_parse_error': "There was a problem parsing the %s, please check the file (%s)",
+                        'recipe_parse_error': "There was a problem parsing the recipe, please check the recipe file (%s)",
+                        'package_not_exist': "The default package(%s) does not exist.",
+                        'dependency_not_exist': "The %s needed by %s does not exist. should be checked for repository",
+                        'server_error': "there was a problem servicing your request. please try again later" }
+                       }
+    
+    DEFAULT_TIC = {'setting': {
+                       'tempdir': '/var/tmp/tic-core',
+                       'cachedir': '/var/tmp/tic-core/cache',
+                       'logdir': '/var/tmp/tic-core/log'},
+                   'server': {
+                       'port': 8082},
+                   'regularexp': {
+                       'meta_prefix': "building-blocks",
+                       'meta_prefix_root': "building-blocks-root-",
+                       'meta_prefix_sub1': "building-blocks-sub1-",
+                       'meta_pattern': "-(?P<meta>root|sub1|sub2)-(?P<pkgname>.+)",    
+                       'meta_sub1_pattern': "(?P<root>.+)-(?P<sub1>.+)",
+                       'meta_sub2_pattern': "(?P<root>.+)-(?P<sub1>.+)-(?P<sub2>.+)",
+                       'profile_pattern': "(?P<pkgname>.+)-profile_(?P<profile>[^-]+)-?(?P<extra>.+)?"}
+                   }
+    
+    _instance = None
+    
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super(ConfigMgr, cls).__new__(cls, *args, **kwargs)
+        return cls._instance
+    
+    def __init__(self, ):
+        self._reset()
+        for conf_path in [DEFAULT_CONF, DEFAULT_MSG_CONF]:
+            self._setConfig(conf_path)
+
+    def _reset(self):
+        for sec, vals in self.DEFAULT_TIC.iteritems():
+            setattr(self, sec, vals)
+        for sec, vals in self.DEFAULT_MESSAGE.iteritems():
+            setattr(self, sec, vals)
+    
+    def _setConfig(self, conf):
+        configParser = ConfigParser.ConfigParser()
+        try:
+            if os.path.exists(conf):
+                configParser.read(conf)
+                for section in configParser.sections():
+                    for option in configParser.options(section):
+                        try:
+                            opt_attr=getattr(self, section)
+                            opt_attr[option]=configParser.get(section, option)
+                        except:
+                            pass
+        except Exception as e:
+            print(e)
+
+configmgr = ConfigMgr()
+
+if __name__ == '__main__':
+    temp_dict = {'aaa': 'bbb'}
+    temp= temp_dict.get(temp_dict.get(None))
+    print(configmgr.setting['cachedir'])
+    print(configmgr.message['repo_not_found'])
+    print(configmgr.regularexp['meta_prefix'])
+    print(configmgr.server['port'])
\ No newline at end of file
index 7617b30..78b8232 100644 (file)
@@ -23,11 +23,15 @@ import logging
 from lxml import etree
 from tic.utils.error import TICError
 from tic.utils.rpmmisc import meetRequireVersion, compare_ver
+from tic.utils.rpmmisc import Dependency
+from tic.config import configmgr
+
+DEFAULT_PROFILE = 'EMPTY'
 
 def analyze_dependency(pkg_group):
     
     def dep_dfs(pkg_id):
-        logger = logging.getLogger(__name__)
+        #logger = logging.getLogger(__name__)
         if pkg_list[pkg_id].get('dependency') is not None:
             return pkg_list[pkg_id].get('dependency')
         
@@ -95,7 +99,24 @@ def analyze_dependency(pkg_group):
 def get_installed_packages(recipe, repoinfo, pkg_group):
     logger = logging.getLogger(__name__)
     
-    def _select_rpm(capability, require):
+    def _select_rpm_from_files(fileList, require):
+        if not fileList or not require:
+            return None
+        # 1. sort
+        fileList.sort()
+        # 2-1. Choose the default rpm or the selected rpm
+        for fname in fileList:
+            file_info = pkg_dict.get(fname)
+            if fname in pkg_set or selected[file_info['id']] >= 1:
+                return file_info
+        # 2-2. Choose the rpm (it does not conflitcs)
+        for fname in fileList:
+            file_info = pkg_dict.get(fname)
+            if not _check_conflicts(file_info):
+                return file_info
+        return pkg_dict.get(fileList[0])
+
+    def _select_rpm(capability, require, recommends=None):
         provide_list = []
         # 1. Choose the rpm included in version from provides
         if require.get('ver'):
@@ -117,24 +138,44 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
             return pkg_dict.get(provide_list[0].get('name'))
         
         # 2 Select one of the rpms by priority
-        # 2-1. Choose the default rpm or the selected rpm 
-        # TODO: default profile rpm should be selected
-        for i in range(0, len(provide_list)):
-            tmp_info = pkg_dict.get(provide_list[i].get('name'))
-            if tmp_info['name'] in pkg_set or selected[tmp_info['id']] >= 1:
-                return tmp_info
-        # 2-2. Select the latest version of rpm
+        # 2-1. Choose the default rpm or the selected rpm        
+        for pro in provide_list:
+            provide_info = pkg_dict.get(pro.get('name'))
+            if provide_info['name'] in pkg_set or selected[provide_info['id']] >= 1:
+                return provide_info
+
+        # 2-2. Choose the defualt profile
+        # TODO: should be supported
+        # if provide_info['profile'] == DEFAULT_PROFILE:
+            # return provide_info
+
+        # 2.3. Choose recommends pkg (pkg-name or capability)
+        if recommends:
+            for pro in provide_list:
+                provide_info = pkg_dict.get(pro.get('name'))
+                for reco in recommends:
+                    # 2-3 Case. select a pkg that is named
+                    if reco['name'] == provide_info['name']:
+                        return provide_info
+                    # 2-3 Case. select a pkg that provides
+                    for cap in provide_info.get('provides'):
+                        if reco['name'] == cap['name']:
+                            return provide_info
+        # 2-4. Select the latest version of rpm
         max_ver = None
-        for i in range(0, len(provide_list)):
-            if not _check_conflicts(pkg_dict.get(provide_list[i]['name'])):
+        for pro in provide_list:
+            if not _check_conflicts(pkg_dict.get(pro.get('name'))):
                 if max_ver:
-                    cap_info = provide_list[i].get('data')
+                    cap_info = pro.get('data')
                     ret = compare_ver(max_ver.get('data'), cap_info)
-                    # cap_info is greater than max_ver
-                    if ret == -1:
-                        max_ver = provide_list[i]
+                    if ret == 0: # equals
+                        # string compare (compare string lexicographically using ASCII value)
+                        if max_ver.get('name') > pro.get('name'):
+                            max_ver = pro
+                    elif ret == -1: # greater than max_ver
+                        max_ver = pro
                 else:
-                    max_ver = provide_list[i]
+                    max_ver = pro
         
         # all of capability pkg are in conflict
         if max_ver is None:
@@ -188,6 +229,7 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
                     for con in conflicts[pro['name']]:
                         if not con['data'].get('ver') or meetRequireVersion(con['data'], pro):
                             #package conflict
+                            logger.info('Conflict %s and %s' % (pkg_info['name'], con['name']))
                             return True
         
         #2. If the conflict package defined by node is installed
@@ -198,11 +240,13 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
                         pkg = pkg_dict[pro['name']]
                         if selected[pkg['id']] != 0:
                             if not con.get('ver') or meetRequireVersion(con, pkg['version']):
+                                logger.info('Conflict %s and %s' % (pkg_info['name'], pkg['name']))
                                 return True
                 elif con['name'] in pkg_dict:
                     pkg = pkg_dict[con['name']]
                     if selected[pkg['id']] != 0:
                         if not con.get('ver') or meetRequireVersion(con, pkg['version']):
+                            logger.info('Conflict %s and %s' % (pkg_info['name'], pkg['name']))
                             return True
         return False
     
@@ -236,7 +280,7 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
         _add_conflicts(pkg_info)
         
         # Installation dependency analysis of rpm
-        for dep_tag in ['recommends', 'requires']:
+        for dep_tag in [Dependency.REQUIRES, Dependency.RECOMMENDS]:
             if pkg_info.get(dep_tag):
                 for req in pkg_info.get(dep_tag):
                     choose = None
@@ -244,11 +288,21 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
                     if req['name'] in provides:
                         # capability : [provide_rpm_1, provide_rpm_2, ... ] 
                         # Select the rpm that meets the condition (version)
-                        choose = _select_rpm(provides[req['name']], req)
+                        if dep_tag == Dependency.REQUIRES:
+                            choose = _select_rpm(provides[req['name']], req, pkg_info.get('recommends'))
+                        else:
+                            choose = _select_rpm(provides[req['name']], req)
                     elif req['name'] in files:
-                        choose = pkg_dict.get(files[req['name']][0])
+                        choose = _select_rpm_from_files(files[req['name']], req)
+                        #choose = pkg_dict.get(files[req['name']][0])
                     elif req['name'] in pkg_dict:
                         choose = pkg_dict.get(req['name'])
+                    
+                    if dep_tag == Dependency.RECOMMENDS:
+                        # A Recommends B: B is installed when A is installed and B has no conflicts.
+                        if not choose or _check_conflicts(choose):
+                            logger.info('%s recommended by %s is ignored for selection (Conflict)' % (req['name'], pkg_info['name']))
+                            continue
                         
                     if choose:
                         if selected[choose['id']] == 0:
@@ -266,7 +320,7 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
                         _create_reference(pkg_info, choose)
                     else:
                         # the rpm does not exists
-                        logger.info('the capability(%s) needed by %s does not exist. should be checked for error' % (req['name'], pkg_info['name']))
+                        logger.info(configmgr.message['dependency_not_exist'] % (req['name'], pkg_info['name']))
                         progress['status'] = False
                         break                     
             
@@ -381,7 +435,8 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
                     tree = etree.parse(repo.get('comps'))
                     root = tree.getroot()
                 except etree.XMLSyntaxError as e:
-                    raise TICError('group.xml syntax error. %s', e)
+                    logger.info(e)
+                    raise TICError(configmgr.message['xml_parse_error'] % ('group.xml', repo['baseurl']))
                 
                 # Convert groups to packages
                 for elm in root.findall('group'):
@@ -420,7 +475,7 @@ def get_installed_packages(recipe, repoinfo, pkg_group):
                 pro = provides.get(pkg_name)[0]
                 pkg_info = pkg_dict.get(pro['name'])
             else:
-                logger.info('the default package(%s) does not exist.' % pkg_name)
+                logger.info(configmgr.message['package_not_exist'] % pkg_name)
                 continue 
 
         pkg_info['selfChecked'] = True
index 6ddd176..3236b1f 100644 (file)
@@ -26,6 +26,7 @@ import os
 from tic.utils import error
 from tic.utils.file import write, make_dirs
 import yaml
+from tic.config import configmgr
 
 
 def get_default_recipe():
@@ -92,13 +93,16 @@ part /boot/kernel/mod_tizen_tm1/lib/modules --size=12 --ondisk mmcblk0p --fstype
     return recipe
 
 def load_yaml(path):
+    logger = logging.getLogger(__name__)
     try:
         with file(path) as f:
             return yaml.load(f)
-    except IOError:
-        raise error.TICError('cannot read meta file: %s' % path)
-    except:
-        raise error.TICError('yaml format error of meta file: %s' % path)
+    except IOError as err:
+        logger(err)
+        raise error.TICError(configmgr.message['server_error'])
+    except yaml.YAMLError as err:
+        logger(err)
+        raise error.TICError(configmgr.message['recipe_parse_error'] % os.path.basename(path))
     
 
 def convert_recipe_to_yaml(recipe, filepath):
index a7f0c5f..95c6b86 100644 (file)
 # Contributors:
 # - S-Core Co., Ltd
 
+import re
+import logging
 from lxml import etree
 from tic.utils.error import TICError
 from tic.utils.rpmmisc import archPolicies, default_arch
-import logging
-import re
+from tic.config import configmgr
 
-meta_prefix = 'building-blocks'
-meta_prefix_root = 'building-blocks-root-'
-meta_prefix_sub1 = 'building-blocks-sub1-'
-meta_pattern = re.compile(''.join(['^', meta_prefix, '-(?P<meta>root|sub1|sub2)-(?P<pkgname>.+)']), re.I)
-meta_sub1_pattern = re.compile("(?P<root>.+)-(?P<sub1>.+)")
-meta_sub2_pattern = re.compile("(?P<root>.+)-(?P<sub1>.+)-(?P<sub2>.+)")
+# meta pkg
+META_PREFIX = configmgr.regularexp['meta_prefix']
+META_PREFIX_ROOT = configmgr.regularexp['meta_prefix_root']
+META_PREFIX_SUB1 = configmgr.regularexp['meta_prefix_sub1']
+META_PATTERN = re.compile(''.join(['^', META_PREFIX, configmgr.regularexp['meta_pattern']]), re.I)
+META_SUB1_PATTERN = re.compile(configmgr.regularexp['meta_sub1_pattern'])
+META_SUB2_PATTERN = re.compile(configmgr.regularexp['meta_sub2_pattern'])
+# profile pkg
+PROFILE_PATTERN = re.compile(configmgr.regularexp['profile_pattern'])
 
 class RepodataParser(object):
     
@@ -72,24 +76,30 @@ class RepodataParser(object):
             pkg_info['selfChecked'] = False # for web-ui tree
             
             # Parsing meta-pkg using meta naming rule
-            meta_match = meta_pattern.search(pkg_info['name'])
+            meta_match = META_PATTERN.search(pkg_info['name'])
             if meta_match is not None:
                 #print(meta_match.group(0), ', ', meta_match.group('meta'), ', ', meta_match.group('pkgname'))
                 if meta_match.group('meta') == 'root':
                     meta_info['root'].append([pkg_info['name']])
                     pkg_info['meta'] = 'root'
                 elif meta_match.group('meta') == 'sub1':
-                    sub1_match = meta_sub1_pattern.search(meta_match.group('pkgname'))
+                    sub1_match = META_SUB1_PATTERN.search(meta_match.group('pkgname'))
                     meta_info['sub1'].append([pkg_info['name'],
-                                              ''.join([meta_prefix_root, sub1_match.group('root')])])
+                                              ''.join([META_PREFIX_ROOT, sub1_match.group('root')])])
                     pkg_info['meta'] = 'sub1'
                 elif meta_match.group('meta') == 'sub2':
-                    sub2_match = meta_sub2_pattern.search(meta_match.group('pkgname'))
+                    sub2_match = META_SUB2_PATTERN.search(meta_match.group('pkgname'))
                     meta_info['sub2'].append([pkg_info['name'],
-                                              ''.join([meta_prefix_root, sub2_match.group('root')]),
-                                              ''.join([meta_prefix_sub1, sub2_match.group('root'),'-', sub2_match.group('sub1')])])
+                                              ''.join([META_PREFIX_ROOT, sub2_match.group('root')]),
+                                              ''.join([META_PREFIX_SUB1, sub2_match.group('root'),'-', sub2_match.group('sub1')])])
                     pkg_info['meta'] = 'sub2'
-            
+
+            # check profile pkg
+            profile_match = PROFILE_PATTERN.search(pkg_info['name']);
+            if profile_match and profile_match.group('profile'):
+                pkg_info['profile'] = profile_match.group('profile')
+            else:
+                pkg_info['profile'] = None
             
             ver_tag = pkg.find(tag_dic['version'])
             pkg_info['version'] = {'epoch':ver_tag.attrib['epoch'],
@@ -229,6 +239,7 @@ class RepodataParser(object):
         return ret_list
 
     def parse(self):
+        logger = logging.getLogger(__name__)
         if not self.repodata_list:
             return None
         
@@ -238,7 +249,8 @@ class RepodataParser(object):
                 tree = etree.parse(repodata['primary'])
                 xml_list.append(tree.getroot())
         except etree.XMLSyntaxError as e:
-            raise TICError('primary.xml syntax error. %s', e)
+            logger.info(e)
+            raise TICError(configmgr.message['xml_parse_error'] % ('primary', repodata['baseurl']))
         
         tag_dic = self._get_tagname(xml_list[0])
         
index b4d499f..ef508f5 100644 (file)
@@ -30,6 +30,7 @@ from tic.utils import process
 from tic.utils.error import TICError
 from tic.utils.grabber import myurlgrab2
 from tic.utils import misc
+from tic.config import configmgr
 
 def _get_uncompressed_data_from_url(url, filename, proxies=None):
     # download file
@@ -71,6 +72,7 @@ def _get_metadata_from_repo(baseurl, proxies, tempdir, cachedir, reponame, fileh
     return file.copyfile_flock(file_path, filename)
 
 def get_repodata_from_repos(repos, cachedir):
+    logger = logging.getLogger(__name__)
     my_repodata = []
     temp_path = os.path.join(cachedir, 'temp', str(misc.get_timestamp()))
     for repo in repos:
@@ -91,8 +93,9 @@ def get_repodata_from_repos(repos, cachedir):
         try:
             tree = etree.parse(repomd)
             root = tree.getroot()
-        except etree.XMLSyntaxError:
-            raise TICError("Unable to parse repomd.xml. Please check the repomd from repository url(%s)", url)
+        except etree.XMLSyntaxError as e:
+            logger.info(e)
+            raise TICError(configmgr.message['xml_parse_error'] % ('repomd.xml', url))
 
         # make cache_dir
         repo_checksum = hashlib.sha256(open(repomd_file, 'rb').read()).hexdigest()
index 498b4ca..54881e4 100644 (file)
@@ -8,6 +8,7 @@ import os
 import logging
 from tic import command
 from tic.utils import error
+from tic.config import configmgr
 
 app = Flask(__name__)
 
@@ -32,9 +33,9 @@ def analysis():
     except ValueError as ve:
         logger.error(ve)
         resp = makeresponse(str(ve), ve)
-    except Exception as ex:
-        logger.error(ex)
-        resp = makeresponse(str(ex), ex)
+    except Exception as ex:
+        logger.error(ex)
+        resp = makeresponse(str(ex), ex)
     
     return resp
 
@@ -67,6 +68,8 @@ def start(port_num=8082):
         print(url_for('index'))
         print(url_for('analysis'))
         print(url_for('exports'))
+    if isinstance(port_num, (str, unicode)):
+        port_num = int(port_num)
     app.run(host='0.0.0.0', threaded=True, port=port_num)
 
 
index e361097..e74eddc 100644 (file)
@@ -37,9 +37,4 @@ class TICError(Exception):
     def __repr__(self):
         if not hasattr(self, 'keyword') or not self.keyword:
             self.keyword = self.__class__.__name__
-        return "<%s> %s" % (self.keyword, str(self))
-    
-
-class RepoError(TICError):
-    """ Error class for Repository related """
-    keyword = 'Repository'
\ No newline at end of file
+        return "<%s> %s" % (self.keyword, str(self))
\ No newline at end of file
index ebcd054..037f95d 100644 (file)
@@ -24,16 +24,18 @@ import logging
 import urllib2
 import contextlib
 from urlgrabber import grabber
-from tic.utils.error import TICError, RepoError
+from tic.utils.error import TICError
 from tic.utils import process
 from tic.utils.file import copyfile
+from tic.config import configmgr
 
 def myurlgrab2(url, filename):
     logger = logging.getLogger(__name__)
     if url.startswith("file:/"):
         filepath = "/%s" % url.replace("file:", "").lstrip('/')
         if not os.path.exists(filepath):
-            raise RepoError("URLGrabber error: can't find file %s" % url)
+            logger.info('URLGrabber error: cannot find file %s'  % url)
+            raise TICError("URLGrabber error: can't find file %s" % url)
         if url.endswith('.rpm'):
             return filepath
         else:
@@ -44,13 +46,17 @@ def myurlgrab2(url, filename):
             with contextlib.closing(urllib2.urlopen(url)) as op:
                 with open(filename, 'w') as f:
                     f.write(op.read())
-            logger.info('download file from ' + str(url))
+            logger.info('download file from %s' % str(url))
         except urllib2.HTTPError as err:
             if err.code == 404:
-                msg = 'The requested url was not found (%s)' % url
+                msg = configmgr.message['repo_not_found'] % url
             else:
                 msg = str(err)
+            logger.info(err)
             raise TICError(msg)
+        except urllib2.URLError as err:
+            logger.info(err)
+            raise TICError(configmgr.message['server_error'])
     return filename
 
 def myurlgrab(url, filename, proxies, progress_obj = None):
@@ -59,7 +65,7 @@ def myurlgrab(url, filename, proxies, progress_obj = None):
     if url.startswith("file:/"):
         filepath = "/%s" % url.replace("file:", "").lstrip('/')
         if not os.path.exists(filepath):
-            raise RepoError("URLGrabber error: can't find file %s" % url)
+            raise TICError("URLGrabber error: can't find file %s" % url)
         if url.endswith('.rpm'):
             return filepath
         else:
index 92c5911..d53b28d 100644 (file)
 
 import rpm
 
+class Dependency(object):
+    REQUIRES='requires'
+    RECOMMENDS='recommends'
+    SUGGESTS='suggests'
+    PROVIDES='provides'
+    CONFILCTS='conflicts'
+
+
 default_arch = ('noarch', 'src')
 
 archPolicies = {
index 9cda680..8c24c8d 100644 (file)
@@ -30,6 +30,7 @@ from tic.utils import log
 from tic.utils import file
 from tic.utils import error
 from tic.server import tic_server
+from tic.config import configmgr
 
 __version__ = 0.1
 __date__ = '2016-11-07'
@@ -63,8 +64,8 @@ def create_parser():
     parser_create.add_argument('-k', "--ks", dest="kickstart", metavar="kickstart", help="ks file to be used for image creation")
     parser_create.add_argument('-o', "--outdir", dest="outdir", action="store", help="image output directory", default=os.getcwd())
     
-    parser_start = subparsers.add_parser('start', help='start the tic-core demon on system. port 8082 is used by default ')
-    parser_start.add_argument('-p', "--port", dest="port", action="store", help="port number", default=8082)
+    parser_start = subparsers.add_parser('start', help='start the tic-core demon on system.')
+    parser_start.add_argument('-p', "--port", dest="port", action="store", help="port number")
     
     return parser
 
@@ -92,7 +93,9 @@ def main(argv):
             else:
                 logger.info('kickstart or recipes file is required')
         elif args.subparser_name == 'start':
-            tic_server.start(int(args.port))
+            if not args.port:
+                args.port = configmgr.server['port']
+            tic_server.start(args.port)
         return 0
     except KeyboardInterrupt:
         ### handle keyboard interrupt ###