rgrunber

Tag: eclipse ide

Eclipse inside a Docker Container

I remember having to use mock to test Fedora Eclipse from different releases, and the main reason I used this was to avoid having to create a VM. While there might be some cases today where I’d go through all that (depending on what I’d need to test), Docker images and containers offer an easy way to run Eclipse.

FROM fedora:22
RUN useradd me
RUN dnf install -y eclipse-pde
COPY ./init.sh /
RUN chmod a+x init.sh
CMD [ "/init.sh" ]
#! /bin/bash

usermod -u $MY_UID -g $MY_GID me
su me -c eclipse

From here, we simply build the image, giving the path to the folder containing the Dockerfile and the init.sh file.

docker build -t eclipse .
...
docker run --rm --privileged -v /tmp/.X11-unix/:/tmp/.X11-unix/ -e DISPLAY=$DISPLAY -e MY_UID=$(id -u) -e MY_GID=$(id -g) eclipse

We ran the image in privileged mode, mounting the X11 socket, with the necessary environment variables. To keep from building up containers, we remove them upon exit.

The Eclipse instance should begin rendering within the host machine’s display. There have been a few cases where newer major versions of Eclipse had to be packaged as Copr repos because it wasn’t feasible to update the many required dependencies for a released version of Fedora. This approach seems like a nice way of getting the latest and greatest on an older host, or even testing an older release on a newer host.

If you’d like to use the graphics libraries from the container’s OS version, that can be done as well.

FROM fedora:22
RUN useradd me
RUN dnf install -y mutter gnome-settings-daemon tigervnc-server-minimal eclipse-pde
COPY ./init.sh /
RUN chmod a+x init.sh
CMD [ "/init.sh" ]
#! /bin/bash

# Set d-bus machine-id
if [ ! -e /etc/machine-id ]; then
  dbus-uuidgen > /etc/machine-id
fi

# Properly start d-bus
mkdir -p /var/run/dbus
dbus-daemon --system

rm -f /tmp/.X*-lock
Xvnc -SecurityTypes=none :3 &
mutter -d :3 &
su me -c eclipse

We build the image exactly as before and our image run command even becomes a little simpler. After the container is started, we connect to it on display :3 using a VNC client (eg. vncviewer from tigervnc), to see the running Eclipse instance.

$ docker build -t eclipse .
...
$ docker run --rm -it --privileged -e DISPLAY=:3 eclipse
...
$ vncviewer 172.17.0.2:3

 

Improving Eclipse Platform Stability On Rawhide

The Eclipse platform on Fedora Rawhide can be pretty unstable at times. Every update to one of its dependencies requires a rebuild. As a result, it has been on our TODO list for a while to work out some way of making Eclipse more resilient to these kind of dependency updates (at least in cases where a rebuild shouldn’t be required). Looking upstream, there are quite a few bugs relating to this topic (410710, 410785, 408138) .

For simple rebuilds where project metadata likely hasn’t changed there’s fix for symbolic links in place.

Another common breakage happens when dependencies that are listed as plugins within a feature get updated.

Unlike regular Eclipse plugins that might contribute certain capabilities, a feature represents a set of plugins. One can think of them as RPM meta-packages and some features are used especially by end-users to install a larger set of plugins (eg. org.eclipse.cdt.feature.group is “C/C++ Development Tools”). A feature lists the set of plugins it provides with the <plugin> tag and may also specify dependencies with the <requires> tag. The difference is that the <plugin> tag locks onto the exact version discovered at build time, and may only resolve against that exact version. The <requires> tag on the other hand allows you some flexibility in terms of dependencies with ranges and some compatibility levels.

Sometimes one might see features listing dependencies as content. Does the JDT provide, or own org.junit and org.hamcrest ? Do we really mean to say that changing the versions of those plugins implies a completely different feature ? Clearly this isn’t the case, and it would make much more sense to use <requires> but the former practice seems quite common.

I don’t think this is done out of lack of understanding, but because projects also want to include their dependencies into the repositories they deploy. The <plugin> definition accomplishes this. Using <requires> one would also need to list the plugins to be included in the repository definition (site.xml/category.xml) and some platform projects have to jump through some additional hoops to change this file so it’s not a huge surprise that many go for the simpler option. Sadly, this causes some problems for us in Fedora land.

Luckily there’s now fix for platform features that should help reduce the number of rebuilds.

DIY Bodhi

A little while ago I was asked about how one would go about testing Eclipse Fedora Packager’s Bodhi functionality. Unfortunately it’s not too often that I, or someone else may push an update that coincides with testing.

There’s the Fedora Bodhi Staging instance but even that approach assumes you have an FAS account with the ability to push updates. Also, the person who asked about this didn’t have an account on the staging instance (I guess a combination of having a newer account, and the staging instance database not being updated that often ?)

The last approach I considered, turned out to be the simplest. Create your own Bodhi instance! Instructions are here.

I had some issues compiling on Fedora 18 with fedmsg, so I disabled calls to fedmsg.publish, but for the kind of testing planned that’s not really too important. When determining if a package will be pushed, Bodhi consults the buildsystem to determine whether the action is valid. By default, the buildsystem is a mocked up version of Koji (buildsystem = ‘dev’) that will perform almost any action. You could also set the buildsystem to be Fedora Koji, or maybe even point it to your own Koji instance. This other patch also needed to be applied if you leave your Bodhi instance using the ‘dev’ configuration to properly handle the tags.

From 35874774d8a36bbe11e887968e956721a95c582d Mon Sep 17 00:00:00 2001
From: Roland Grunberg <rgrunber@redhat.com>
Date: Fri, 31 May 2013 18:26:33 -0400
Subject: [PATCH 1/2] Disable fedmsg.publish, and modify to use with Eclipse
 PyDev.

---
 Makefile       |  2 +-
 bodhi/model.py | 52 ++++++++++++++++++++++++++--------------------------
 setup.py       |  2 +-
 start-bodhi    | 13 -------------
 start-bodhi.py | 13 +++++++++++++
 5 files changed, 41 insertions(+), 41 deletions(-)
 delete mode 100755 start-bodhi
 create mode 100755 start-bodhi.py

diff --git a/Makefile b/Makefile
index a8968ec..5d125d1 100644
--- a/Makefile
+++ b/Makefile
@@ -56,7 +56,7 @@ init:
 	rm bodhi-pickledb-*

 run:
-	python start-bodhi
+	python start-bodhi.py

 profile:
 	nosetests --with-profile --profile-stats-file=nose.prof
diff --git a/bodhi/model.py b/bodhi/model.py
index 81e6743..24a5f4d 100644
--- a/bodhi/model.py
+++ b/bodhi/model.py
@@ -43,7 +43,7 @@ try:
 except ImportError:
     from fedora.tg.util import tg_url

-import fedmsg
+#import fedmsg

 from bodhi import buildsys, mail
 from bodhi.util import get_nvr, rpm_fileheader, header, get_age, get_age_in_days
@@ -448,18 +448,18 @@ class PackageUpdate(SQLObject):
             self.unpush()
             self.comment('This update has been unpushed',
                          author=identity.current.user_name)
-            fedmsg.publish(topic=fedmsg_topic, msg=dict(
-                update=self,
-                agent=identity.current.user_name,
-            ))
+            #fedmsg.publish(topic=fedmsg_topic, msg=dict(
+            #    update=self,
+            #    agent=identity.current.user_name,
+            #))
             flash_log("%s has been unpushed" % self.title)
             return
         elif action == 'obsolete':
             self.obsolete()
-            fedmsg.publish(topic=fedmsg_topic, msg=dict(
-                update=self,
-                agent=identity.current.user_name,
-            ))
+            #fedmsg.publish(topic=fedmsg_topic, msg=dict(
+            #    update=self,
+            #    agent=identity.current.user_name,
+            #))
             flash_log("%s has been obsoleted" % self.title)
             return
         #elif self.type == 'security' and not self.approved:
@@ -489,10 +489,10 @@ class PackageUpdate(SQLObject):
                                                           mybuild['nvr']))
         elif action == 'revoke':
             if self.request:
-                fedmsg.publish(topic=fedmsg_topic, msg=dict(
-                    update=self,
-                    agent=identity.current.user_name,
-                ))
+                #fedmsg.publish(topic=fedmsg_topic, msg=dict(
+                #    update=self,
+                #    agent=identity.current.user_name,
+                #))
                 flash_log('%s %s request revoked' % (self.title, self.request))
                 self.request = None
                 self.comment('%s request revoked' % action,
@@ -575,10 +575,10 @@ class PackageUpdate(SQLObject):
             action, notes, flash_notes))
         self.comment('This update has been submitted for %s by %s. %s' % (
             action, identity.current.user_name, notes), author='bodhi')
-        fedmsg.publish(topic='update.request.' + action, msg=dict(
-            update=self,
-            agent=identity.current.user_name,
-        ))
+        #fedmsg.publish(topic='update.request.' + action, msg=dict(
+        #    update=self,
+        #    agent=identity.current.user_name,
+        #))
         mail.send_admin(action, self)

     def request_complete(self):
@@ -900,11 +900,11 @@ class PackageUpdate(SQLObject):
         if email:
             mail.send(self.people_to_notify(), 'comment', self)

-        if author not in ('bodhi', 'autoqa'):
-            fedmsg.publish(topic='update.comment', msg=dict(
-                comment=c,
-                agent=identity.current.user_name
-            ))
+        #if author not in ('bodhi', 'autoqa'):
+        #    fedmsg.publish(topic='update.comment', msg=dict(
+        #        comment=c,
+        #        agent=identity.current.user_name
+        #    ))

         if self.critpath:
             min_karma = config.get('critpath.min_karma')
@@ -1565,10 +1565,10 @@ class BuildRootOverride(SQLObject):
             self.release.override_tag))
         koji.tagBuild(self.release.override_tag, self.build, force=True)
         mail.send_admin('buildroot_override', self)
-        fedmsg.publish(
-            topic='buildroot_override.tag',
-            msg=dict(override=self, agent=identity.current.user_name),
-        )
+        #fedmsg.publish(
+        #    topic='buildroot_override.tag',
+        #    msg=dict(override=self, agent=identity.current.user_name),
+        #)

     def untag(self):
         koji = buildsys.get_session()
diff --git a/setup.py b/setup.py
index 5207f10..afa5acb 100755
--- a/setup.py
+++ b/setup.py
@@ -174,7 +174,7 @@ setup(
         "kitchen",
         "python-fedora",
         #"hashlib",
-        "fedmsg>=0.0.8",
+        #"fedmsg>=0.0.8",
         "decorator",
         "PIL",
         # The following are not available as eggs so we can't uncomment them.
diff --git a/start-bodhi b/start-bodhi
deleted file mode 100755
index 5896d0f..0000000
--- a/start-bodhi
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/python -tt
-""" Start script for bodhi """
-__requires__='bodhi'
-from bodhi.commands import start, ConfigurationError
-
-if __name__ == '__main__':
-    try:
-        start()
-    except ConfigurationError, exc:
-        import sys
-        sys.stderr.write(str(exc))
-        sys.exit(1)
-
diff --git a/start-bodhi.py b/start-bodhi.py
new file mode 100755
index 0000000..5896d0f
--- /dev/null
+++ b/start-bodhi.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python -tt
+""" Start script for bodhi """
+__requires__='bodhi'
+from bodhi.commands import start, ConfigurationError
+
+if __name__ == '__main__':
+    try:
+        start()
+    except ConfigurationError, exc:
+        import sys
+        sys.stderr.write(str(exc))
+        sys.exit(1)
+
--
1.8.1.4

and

From 9ab7e42232343fff065dbabb91b3c4dcc3193a65 Mon Sep 17 00:00:00 2001
From: Roland Grunberg <rgrunber@redhat.com>
Date: Fri, 31 May 2013 19:35:28 -0400
Subject: [PATCH 2/2] Add rule for the usage of the 'dist' prefix.

The dist prefix has not been used since f15.
---
 bodhi/buildsys.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/bodhi/buildsys.py b/bodhi/buildsys.py
index bf7128c..c3cf9a0 100644
--- a/bodhi/buildsys.py
+++ b/bodhi/buildsys.py
@@ -184,12 +184,13 @@ class DevBuildsys(Buildsystem):
                      'name': 'dist-5E-epel', 'perm': None, 'perm_id': None}]
         else:
             release = build.split('.')[-1].replace('fc', 'f')
+            distStr = "" if int(release[1:]) > 15 else "dist-"
             return [{'arches': 'i386 x86_64 ppc ppc64', 'id': 10, 'locked': True,
-                     'name': 'dist-%s-updates-candidate' % release, 'perm': None, 'perm_id': None},
+                     'name': distStr + '%s-updates-candidate' % release, 'perm': None, 'perm_id': None},
                     {'arches': 'i386 x86_64 ppc ppc64', 'id': 5, 'locked': True,
-                     'name': 'dist-%s' % release, 'perm': None, 'perm_id': None},
+                     'name': distStr + '%s' % release, 'perm': None, 'perm_id': None},
                     {'arches': 'i386 x86_64 ppc ppc64', 'id': 5, 'locked': True,
-                     'name': 'dist-%s-updates-testing' % release, 'perm': None, 'perm_id': None}]
+                     'name': distStr + '%s-updates-testing' % release, 'perm': None, 'perm_id': None}]

     def listTagged(self, tag, *args, **kw):
         return [self.getBuild(), self.getBuild(other=True)]
--
1.8.1.4

After applying those changes, I pretty much had a working local Bodhi instance that could push updates.

eclipse-bodhi-instance

Just about everything could be done within Fedora Eclipse, using the Eclipse Pydev plugin (yum install eclipse-pydev).