commit:     e940caa7779d5d0f0e3864670723e0ea3a0b3e1d
Author:     Magnus Granberg <zorry <AT> gentoo <DOT> org>
AuthorDate: Sat Mar 13 18:39:23 2021 +0000
Commit:     Magnus Granberg <zorry <AT> gentoo <DOT> org>
CommitDate: Sat Mar 13 18:39:23 2021 +0000
URL:        
https://gitweb.gentoo.org/proj/tinderbox-cluster.git/commit/?id=e940caa7

Add support to use db for portage config insted of repo on local worker

Signed-off-by: Magnus Granberg <zorry <AT> gentoo.org>

 buildbot_gentoo_ci/config/builders.py      |   3 +
 buildbot_gentoo_ci/config/buildfactorys.py |  27 +++---
 buildbot_gentoo_ci/steps/portage.py        | 106 ++++++++++++++++++++++
 buildbot_gentoo_ci/steps/update_db.py      | 140 +++++++++++++++++++----------
 4 files changed, 218 insertions(+), 58 deletions(-)

diff --git a/buildbot_gentoo_ci/config/builders.py 
b/buildbot_gentoo_ci/config/builders.py
index cba9fcc..c7b4469 100644
--- a/buildbot_gentoo_ci/config/builders.py
+++ b/buildbot_gentoo_ci/config/builders.py
@@ -9,6 +9,7 @@ def gentoo_builders(b=[]):
     b.append(util.BuilderConfig(
         name='update_db_check',
         workername='updatedb_1',
+        workerbuilddir='builds',
         factory=buildfactorys.update_db_check()
         )
     )
@@ -19,6 +20,7 @@ def gentoo_builders(b=[]):
     b.append(util.BuilderConfig(
         name='update_cpv_data',
         workername='updatedb_1',
+        workerbuilddir='builds',
         factory=buildfactorys.update_db_cp()
         )
     )
@@ -27,6 +29,7 @@ def gentoo_builders(b=[]):
     b.append(util.BuilderConfig(
         name='update_v_data',
         workername='updatedb_1',
+        workerbuilddir='builds',
         factory=buildfactorys.update_db_v()
         )
     )

diff --git a/buildbot_gentoo_ci/config/buildfactorys.py 
b/buildbot_gentoo_ci/config/buildfactorys.py
index 31543f9..f5a3b35 100644
--- a/buildbot_gentoo_ci/config/buildfactorys.py
+++ b/buildbot_gentoo_ci/config/buildfactorys.py
@@ -15,20 +15,21 @@ def update_db_check():
     f = util.BuildFactory()
     # FIXME: 1
     # Get base project data from db
-    #   return project_repository, profile_repository,
-    #       project
+    #   return profile_repository, project
     f.addStep(update_db.GetDataGentooCiProject())
-    # Check if base project repo is cloned
-    # Check if profile repo is cloned
-    # check if the profile link is there
-    # check if the repository is cloned
-    f.addStep(update_db.CheckPathGentooCiProject())
-    # check if etc/portage has no error
-    #   return config_root
-    f.addStep(update_db.CheckProjectGentooCiProject())
-    # Make a for loop and trigger new builders with cpv from cpv_changes
-    #   return cpv, repository, project_data, config_root
-    f.addStep(update_db.CheckCPVGentooCiProject())
+    # Check if needed path is there
+    f.addStep(update_db.CheckPath())
+    # update the repos
+    f.addStep(update_db.UpdateRepos())
+    # setup the profile
+    f.addStep(portage.SetMakeProfileLocal())
+    # setup repos.conf dir
+    f.addStep(portage.SetReposConfLocal())
+    # setup make.conf
+    f.addStep(portage.SetMakeConfLocal())
+    # Make a for loop and trigger new builders with cpv from git_changes
+    #   return cpv, repository, project_data
+    f.addStep(update_db.TriggerCheckForCPV())
     return f
 
 def update_db_cp():

diff --git a/buildbot_gentoo_ci/steps/portage.py 
b/buildbot_gentoo_ci/steps/portage.py
index 30361e6..4fbe141 100644
--- a/buildbot_gentoo_ci/steps/portage.py
+++ b/buildbot_gentoo_ci/steps/portage.py
@@ -11,6 +11,15 @@ from buildbot.process.results import SUCCESS
 from buildbot.process.results import FAILURE
 from buildbot.plugins import steps
 
[email protected]
+def WriteTextToFile(path, text_list):
+    separator = '\n'
+    text_string = separator.join(text_list)
+    with open(path, "a") as f:
+        yield f.write(text_string)
+        yield f.write(separator)
+        yield f.close
+
 class SetMakeProfile(BuildStep):
 
     name = 'SetMakeProfile'
@@ -292,3 +301,100 @@ class SetEnvDefault(BuildStep):
             ])
         yield self.build.addStepsAfterCurrentStep(aftersteps_list)
         return SUCCESS
+
+class SetMakeProfileLocal(BuildStep):
+
+    name = 'SetMakeProfileLocal'
+    description = 'Running'
+    descriptionDone = 'Ran'
+    descriptionSuffix = None
+    haltOnFailure = True
+    flunkOnFailure = True
+
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+
+    @defer.inlineCallbacks
+    def run(self):
+        parent_path = yield os.path.join('portage', 'make.profile', 'parent')
+        if os.path.isfile(parent_path):
+            return SUCCESS
+        self.gentooci = 
self.master.namedServices['services'].namedServices['gentooci']
+        self.repository_basedir = 
self.gentooci.config.project['repository_basedir']
+        makeprofiles_paths = []
+        makeprofiles_data = yield 
self.gentooci.db.projects.getAllProjectPortageByUuidAndDirectory(self.getProperty('project_data')['uuid'],
 'make.profile')
+        for makeprofile in makeprofiles_data:
+            makeprofile_path = yield os.path.join(self.repository_basedir, 
self.getProperty("profile_repository_data")['name'], 'profiles', 
makeprofile['value'], '')
+            makeprofiles_paths.append('../../' + makeprofile_path)
+        yield WriteTextToFile(parent_path, makeprofiles_paths)
+        return SUCCESS
+
+class SetReposConfLocal(BuildStep):
+
+    name = 'SetReposConfLocal'
+    description = 'Running'
+    descriptionDone = 'Ran'
+    descriptionSuffix = None
+    haltOnFailure = True
+    flunkOnFailure = True
+
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+
+    @defer.inlineCallbacks
+    def run(self):
+        repos_conf_path = yield os.path.join('portage', 'repos.conf')
+        repos_conf_default_path = yield os.path.join(repos_conf_path, 
'default.conf')
+        self.gentooci = 
self.master.namedServices['services'].namedServices['gentooci']
+        self.repository_basedir = 
self.gentooci.config.project['repository_basedir']
+        if not os.path.isfile(repos_conf_default_path):
+            # setup the default.conf
+            repos_conf_data = yield 
self.gentooci.db.projects.getProjectPortageByUuidAndDirectory(self.getProperty('project_data')['uuid'],
 'repos.conf')
+            if repos_conf_data is None:
+                print('Default repo is not set in repos.conf')
+                return FAILURE
+            default_conf = []
+            default_conf.append('[DEFAULT]')
+            default_conf.append('main-repo = ' + repos_conf_data['value'])
+            default_conf.append('auto-sync = no')
+            yield WriteTextToFile(repos_conf_default_path, default_conf)
+        repos_conf_repository_path = yield os.path.join(repos_conf_path, 
self.getProperty("repository_data")['name'] + '.conf')
+        if not os.path.isfile(repos_conf_repository_path):
+            repository_path = yield os.path.join(self.repository_basedir, 
self.getProperty("repository_data")['name'])
+            repository_conf = []
+            repository_conf.append('[' + 
self.getProperty("repository_data")['name'] + ']')
+            repository_conf.append('location = ' + repository_path)
+            repository_conf.append('sync-uri = ' + 
self.getProperty("repository_data")['mirror_url'])
+            repository_conf.append('sync-type = git')
+            repository_conf.append('auto-sync = no')
+            yield WriteTextToFile(repos_conf_repository_path, repository_conf)
+        return SUCCESS
+
+class SetMakeConfLocal(BuildStep):
+
+    name = 'SetMakeConfLocal'
+    description = 'Running'
+    descriptionDone = 'Ran'
+    descriptionSuffix = None
+    haltOnFailure = True
+    flunkOnFailure = True
+
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+
+    @defer.inlineCallbacks
+    def run(self):
+        make_conf_path = yield os.path.join('portage', 'make.conf')
+        if os.path.isfile(make_conf_path):
+            return SUCCESS
+        makeconf_list = []
+        makeconf_list.append('CFLAGS=""')
+        makeconf_list.append('CXXFLAGS=""')
+        makeconf_list.append('ACCEPT_LICENSE="*"')
+        makeconf_list.append('USE=""')
+        makeconf_list.append('ACCEPT_KEYWORDS="~amd64 amd64"')
+        makeconf_list.append('EMERGE_DEFAULT_OPTS=""')
+        makeconf_list.append('ABI_X86="32 64"')
+        makeconf_list.append('FEATURES=""')
+        yield WriteTextToFile(make_conf_path, makeconf_list)
+        return SUCCESS

diff --git a/buildbot_gentoo_ci/steps/update_db.py 
b/buildbot_gentoo_ci/steps/update_db.py
index 94d0b4f..bfcd2ef 100644
--- a/buildbot_gentoo_ci/steps/update_db.py
+++ b/buildbot_gentoo_ci/steps/update_db.py
@@ -2,6 +2,7 @@
 # Distributed under the terms of the GNU General Public License v2
 
 import os
+import pygit2
 
 from portage import config as portage_config
 from portage.versions import catpkgsplit
@@ -15,8 +16,6 @@ from buildbot.process.results import SUCCESS
 from buildbot.process.results import FAILURE
 from buildbot.plugins import steps
 
-#from buildbot_gentoo_ci.steps.updatedb_functions import category
-
 class GetDataGentooCiProject(BuildStep):
 
     def __init__(self, **kwargs):
@@ -29,16 +28,11 @@ class GetDataGentooCiProject(BuildStep):
         if self.project_data is None:
             log.err('No data for project in the database')
             return FAILURE
-        self.project_repository_data = yield 
self.gentooci.db.repositorys.getRepositoryByUuid(self.project_data['project_repository_uuid'])
-        if self.project_repository_data is None:
-            log.err('No data for repository in the database')
-            return FAILURE
         self.profile_repository_data = yield 
self.gentooci.db.repositorys.getRepositoryByUuid(self.project_data['profile_repository_uuid'])
         if self.profile_repository_data is None:
             log.err('No data for repository in the database')
             return FAILURE
         print(self.project_data)
-        print(self.project_repository_data)
         print(self.profile_repository_data)
         print(self.getProperty("git_changes"))
         print(self.getProperty("repository"))
@@ -51,12 +45,18 @@ class GetDataGentooCiProject(BuildStep):
         if repository:
             self.repository_data = yield 
self.gentooci.db.repositorys.getRepositoryByName(repository)
         self.setProperty("project_data", self.project_data, 'project_data')
-        self.setProperty("project_repository_data", 
self.project_repository_data, 'project_repository_data')
         self.setProperty("profile_repository_data", 
self.profile_repository_data, 'profile_repository_data')
         self.setProperty("repository_data", self.repository_data, 
'repository_data')
         return SUCCESS
 
-class CheckPathGentooCiProject(BuildStep):
+class CheckPath(BuildStep):
+
+    name = 'CheckPath'
+    description = 'Running'
+    descriptionDone = 'Ran'
+    descriptionSuffix = None
+    haltOnFailure = True
+    flunkOnFailure = True
 
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
@@ -65,59 +65,110 @@ class CheckPathGentooCiProject(BuildStep):
     def run(self):
         self.gentooci = 
self.master.namedServices['services'].namedServices['gentooci']
         self.repository_basedir = 
self.gentooci.config.project['repository_basedir']
-        self.profile_repository_data = 
self.getProperty("profile_repository_data")
-        self.project_repository_data = 
self.getProperty("project_repository_data")
-        self.repository_data = self.getProperty("repository_data")
-        self.project_data = self.getProperty("project_data")
-        self.project_path = yield os.path.join(self.repository_basedir, 
self.project_repository_data['name'] + '.git')
-        self.repository_path = yield os.path.join(self.repository_basedir, 
self.repository_data['name'] + '.git')
-        self.portage_path = yield os.path.join(self.project_path, 
self.project_data['name'], 'etc/portage')
+        self.portage_path = 'portage'
+        self.profile_path = yield os.path.join(self.portage_path, 
'make.profile')
+        self.repos_path = yield os.path.join(self.portage_path, 'repos.conf')
+        print(os.getcwd())
+        print(self.getProperty("builddir"))
+        yield os.chdir(self.getProperty("builddir"))
         success = True
+        print(os.getcwd())
         for x in [
-                  os.path.join(self.repository_basedir, 
self.profile_repository_data['name'] + '.git'),
-                  self.project_path,
-                  self.portage_path,
-                  os.path.join(self.portage_path, 'make.profile'),
-                  self.repository_path
-                  # check the path of make.profile is project_data['profile']
+                  self.profile_path,
+                  self.repos_path,
+                  self.repository_basedir
                  ]:
-            is_dir = True
             if not os.path.isdir(x):
-                is_dir  = False
-                success = False
-            print("isdir(%s): %s" %(x, is_dir))
-        print(self.getProperty("builddir"))
-        if not success:
-            return FAILURE
+                os.makedirs(x)
         return SUCCESS
 
-class CheckProjectGentooCiProject(BuildStep):
+class UpdateRepos(BuildStep):
+
+    name = 'UpdateRepos'
+    description = 'Running'
+    descriptionDone = 'Ran'
+    descriptionSuffix = None
+    haltOnFailure = True
+    flunkOnFailure = True
+
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
 
+    # Origin: 
https://github.com/MichaelBoselowitz/pygit2-examples/blob/master/examples.py#L54
+    # Modifyed by Gentoo Authors.
+    @defer.inlineCallbacks
+    def gitPull(self, repo, remote_name='origin', branch='master'):
+        for remote in repo.remotes:
+            if remote.name == remote_name:
+                yield remote.fetch()
+                remote_master_id = yield 
repo.lookup_reference('refs/remotes/origin/%s' % (branch)).target
+                merge_result, _ = yield repo.merge_analysis(remote_master_id)
+                # Up to date, do nothing
+                if merge_result & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE:
+                    return
+                # We can just fastforward
+                elif merge_result & pygit2.GIT_MERGE_ANALYSIS_FASTFORWARD:
+                    yield repo.checkout_tree(repo.get(remote_master_id))
+                    try:
+                        master_ref = yield 
repo.lookup_reference('refs/heads/%s' % (branch))
+                        yield master_ref.set_target(remote_master_id)
+                    except KeyError:
+                        yield repo.create_branch(branch, 
repo.get(remote_master_id))
+                    yield repo.head.set_target(remote_master_id)
+                elif merge_result & pygit2.GIT_MERGE_ANALYSIS_NORMAL:
+                    yield repo.merge(remote_master_id)
+
+                    if repo.index.conflicts is not None:
+                        for conflict in repo.index.conflicts:
+                            print('Conflicts found in:', conflict[0].path)
+                        raise AssertionError('Conflicts, ahhhhh!!')
+
+                    user = yield repo.default_signature
+                    tree = yield repo.index.write_tree()
+                    commit = yield repo.create_commit('HEAD',
+                                            user,
+                                            user,
+                                            'Merge!',
+                                            tree,
+                                            [repo.head.target, 
remote_master_id])
+                    # We need to do this or git CLI will think we are still 
merging.
+                    yield repo.state_cleanup()
+                else:
+                    raise AssertionError('Unknown merge analysis result')
+
     @defer.inlineCallbacks
     def run(self):
         self.gentooci = 
self.master.namedServices['services'].namedServices['gentooci']
         self.repository_basedir = 
self.gentooci.config.project['repository_basedir']
-        self.project_repository_data = 
self.getProperty("project_repository_data")
-        self.project_data = self.getProperty("project_data")
-        self.project_path = yield os.path.join(self.repository_basedir, 
self.project_repository_data['name'] + '.git')
-        self.config_root = yield os.path.join(self.project_path, 
self.project_data['name'], '')
-        self.make_conf_file = yield os.path.join(self.config_root, 
'etc/portage', '') + 'make.conf'
-        try:
-            getconfig(self.make_conf_file, tolerant=0, allow_sourcing=True, 
expand=True)
-            mysettings = portage_config(config_root = self.config_root)
-            mysettings.validate()
-        except ParseError as e:
-            print("project portage conf has error %s" %(str(e)))
-            return FAILURE
-        self.setProperty("config_root", self.config_root, 'config_root')
+        self.profile_repository_path = yield 
os.path.join(self.repository_basedir, 
self.getProperty("profile_repository_data")['name'])
+        repo_path = yield 
pygit2.discover_repository(self.profile_repository_path)
+        print(repo_path)
+        if repo_path is None:
+            yield 
pygit2.clone_repository(self.getProperty("profile_repository_data")['mirror_url'],
 self.profile_repository_path)
+        else:
+            repo = yield pygit2.Repository(repo_path)
+            yield self.gitPull(repo)
+        if self.getProperty("profile_repository_data")['name'] != 
self.getProperty("repository_data")['name']:
+            self.repository_path = yield os.path.join(self.repository_basedir, 
self.getProperty("repository_data")['name'])
+            repo_path = yield pygit2.discover_repository(self.repository_path)
+            if repo_path is None:
+                yield 
pygit2.clone_repository(self.getProperty("profile_repository_data")['mirror_url'],
 self.repository_path)
+            else:
+                repo = yield pygit2.Repository(repo_path)
+                yield self.gitPull(repo)
         return SUCCESS
 
-class CheckCPVGentooCiProject(BuildStep):
+class TriggerCheckForCPV(BuildStep):
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
 
+    name = 'TriggerCheckForCPV'
+    description = 'Running'
+    descriptionDone = 'Ran'
+    descriptionSuffix = None
+    haltOnFailure = True
+    flunkOnFailure = True
+
     @defer.inlineCallbacks
     def run(self):
         self.git_changes = self.getProperty("git_changes")
@@ -152,7 +203,6 @@ class CheckCPVGentooCiProject(BuildStep):
                                 updateSourceStamp=False,
                                 set_properties={
                                     'cpv' : cpv,
-                                    'config_root' : 
self.getProperty("config_root"),
                                     'project_data' : 
self.getProperty("project_data"),
                                     'repository_data' : 
self.getProperty("repository_data"),
                                     'revision_data' : revision_data,

Reply via email to