The dm Shell

Chris Frost

The dm Server has a new command line shell. It is currently available along with the existing Equinox shell and will replace it for the 2.0 release. Improvements over the Equinox shell include basic tab completion and a command history.

The dm Shell is available both locally and remotely over ssh. When used locally by starting the server with the './startup.sh -shell' option it will take over the console output once the dm Kernel has started. Console output will still be viewable in the event log. Either way the first thing to be produced is an ASCII art splash image followed by the command prompt ':> '.

[13:36:54 ~]: ssh -p 2402 admin@localhost
admin@localhost's password: 

     @@@ ***
    @@@ *****            .__.                  .__.            .__.  .__.
   @@@@ ******         __|  |  _____     _____.|  |__    ____  |  |  |  |
   @@@@@@ ****        / __  | /     \   /  ___/|  |  \ ./ __ \ |  |  |  |
    @@@@@ ***        / /_/  ||  Y Y  \  \___ \ |   Y  \\  ___/ |  |__|  |__
     @@@ ***         \______||__|_|__/ /_____/ |___|__/ \____/ |____/|____/      

Type 'help' to see the available commands.
:>

When accessing the dm Shell remotely a password is required, security is provided by JAAS authentication and is the same id/password as for the dm Console. The default is 'admin/springsource'. This can be configured from the 'com.springsource.kernel.users.properties' file in the 'config' directory.

Listing bundles

Once in the shell type 'help' to view a list of available of commands. When half way through a command just press 'TAB' to see a list of possible completions for the command instead of going back and typing 'help' again.

Start with the 'bundles' command, this will show the user region bundles in the system. Their state, name, version and whether they are spring powered is shown. With the exception of a few kernel bundles and their services, used to administer the user region, none of the kernel is visible to user installed artifacts. This makes it much clearer as there are far fewer system bundles and services visible.

:> bundles
Id  State         Name-Version
0   Active        org.eclipse.osgi-3.5.1.R35x_v20090827
1   Active        com.springsource.region.user-0.0.0
2   Resolved      org.springframework.aop-3.0.0.CI-395
3   Resolved      org.springframework.asm-3.0.0.CI-395
....
46  Active      S com.springsource.server.admin.web-2.0.0.M5
47  Active        com.springsource.javax.servlet.jsp.jstl-1.1.2
48  Active        com.springsource.org.apache.taglibs.standard-1.1.2
49  Active        org.springframework.context.support-3.0.0.CI-395
50  Active        org.springframework.jdbc-3.0.0.CI-395
51  Active        org.springframework.js-2.0.8.RELEASE
52  Active        org.springframework.transaction-3.0.0.CI-395
53  Active        org.springframework.web.servlet-3.0.0.CI-395
54  Active      S com.springsource.server.repository.hosted-2.0.0.M5-com.springsource.server.repository.hosted.core-2.0.0.M5
55  Active        com.springsource.server.repository.hosted-2.0.0.M5-com.springsource.server.repository.hosted.web-2.0.0.M5
56  Active        com.springsource.server.repository.hosted-2.0.0.M5-com.springsource.server.repository.hosted-synthetic.context-2.0.0.M5
57  Active        com.springsource.server.splash-2.0.0.M5

Performing lifecycle operations

It is easy to perform operations as well, for example installing a bundle. Type 'install file:/path.to.bundle.jar'.

:> install file:/Users/chrisfrost/Desktop/com.bar.import-1.0.0.jar
60  Installed     com.bar.importer-1.0.0

The Bundle has been installed but when we try to 'start' it there is an error. When the attempt was made to start the bundle a missing required dependency for the bundle is shown.

:> start 60
Error occured while starting bundle '[60] com.bar.importer-1.0.0' : The bundle could not be resolved. Reason: Missing Constraint: Import-Package: com.foo; version="[1.0.0,2.0.0)"
:>

It is easy to get this information at any time with the 'diag' command. The information presented will be the same as that displayed in the log files when any attempts are made to start the bundle.

:> diag 60
Resolution report for bundel 60  Installed     com.bar.importer-1.0.0

Cannot resolve: com.bar.importer
    Resolver report:
        An Import-Package could not be resolved. Caused missing constraint <Import-Package: com.foo; version="[1.0.0,2.0.0)"> in bundle <com.bar.importer_1.0.0>

:>

We can install a bundle that satisfies the dependency and then 'start' our original bundle again, this time all goes smoothly.

Bundle details

This is a very simple bundle and it can be viewed in detail by typing 'bundle 60'. Remember there is tab completion so just 'bu TAB 60' will do to complete the command. Here all the packages that this bundle imports and exports are shown. The 'S' before the bundle name indicates that the bundle has a Spring context.

:> bundle 60
Bundle report for 60  Active      S com.bar.importer-1.0.0

Imported packages:
    com.foo-[1.0.0, 2.0.0)

Exported packages:

:> bundle 61
Bundle report for 61  Resolved      com.foo.exporter-1.0.0

Imported packages:

Exported packages:
    com.foo-1.0.0

:>

We can see that it is now importing the package that caused the error before. The second bundle shown is the one that exports that package.

Viewing configuration

Some of the other commands available include 'config' and 'configs', these will display the installed configurations and their properties.

:> configs
Pid
com.springsource.kernel
com.springsource.repository
com.springsource.server.repository.hosted
com.springsource.osgi.medic
com.springsource.kernel.users
com.springsource.kernel.jmxremote.access

:> config com.springsource.osgi.medic
Pid                 = com.springsource.osgi.medic
Factory pid         = null
Bundle location     = null

dump.root.directory = serviceability/dump
log.wrapSysErr      = true
log.wrapSysOut      = true
service.pid         = com.springsource.osgi.medic

:>

Shown is a listing of the available configurations and the properties for the medic configuration. When finished with dm Shell there are two ways to leave it. 'exit' will simply exit the shell while 'shutdown' will call shutdown on the server and the shell session will be terminated as part of the shutdown.

:> exit
Goodbye.
Connection to localhost closed.
[14:24:03 ~]:

Coming soon…

More work is being done on the shell in the run up to the 2.0 release and when that happens there will be a full user guide and I suspect another blog or screencast. So if there is some killer feature that you would like to see then please shout.

Similar Posts

Share this Post
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Slashdot
  • Technorati
  • TwitThis
 

15 responses


  1. Is it possible to add shell commands from a bundle?


  2. Hi,

    Yes, it is possible to do this. It is probable the way it works will change so we haven't publicised it. All of the existing commands are provided in the same way so you can just look at the code in the kernel.shell bundle and copy that.

    In short, you just have to register a service with 2 properties. One property (osgi.command.scope) will give a name to the group of commands you are providing, the other property (osgi.command.function) should be a list of method names that can be called on your service. This will become the list of commands. That is all there is to it, the shell will sort out the rest.

    Thanks, and good luck.


  3. What was the reason for creating a new one instead of enhancing the Equinox console?


  4. @Gunnar,

    Based on discussions in the Equinox dev list [http://j.mp/LQSyT], the Equinox team does not see the current console implementation surviving beyond the release of the RFC 147 (Command Line Interface) specification. Because of that, it didn't seem prudent to write extensions to the existing console knowing that they were already obsolete.

    When RFC 147 does become final, the dm Shell will likely implement that spec and allow the use of any compliant extension.


  5. Ouch. Did you really read that out of this statement? As I read it – and from my experience with the Equinox team – the Equinox console will somehow continue. They are even looking for someone to take over responsibility and continue developing it.

    Another question … will your console work with other OSGi frameworks, i.e. just a bundle I install and ready to run?


  6. @Gunnar,

    I agree that they are looking to continue it, but within the realm of RFC 147. This RFC defines a completely different extension mechanism than what they have now. Our concern is not that the console won't continue, but rather the extension model will change.

    Our console will not work on a generic OSGi framework as it uses dm Server internals to support a richer type model than an OSGi framework handles.


  7. I have really found debugging very difficult when i have many bundles installed.

    It would be a great help if some utility commands can be provided in the console which will help me in debugging.

    My great concern was import/export packages and sometime i run with uses conflict.

    During this time some utility like

    Given a package name – i want the bundles exposing it

    – different versions available along with bundles exposing it.

    Some tree structure which helps me resolve uses conflict etc would be greatly appreciated.

    Regards,
    Sudheer Krishna


  8. Hi,

    just two suggestions:
    1. we're using dm Servers "Bundle Overview" tab inside of STS very often to resolve resolution errors as it shows which of the exported services are currently being consumed by which other bundles. It would be nice if you could enrich the output of the "bundle details" command mentioned above with this information

    2. Enhance dm Server-Hyperic HQ integration in the way that
    a) the dm Shell of the currently selected dm Server node can be accessed from within Hyperic
    b) ONE dm Shell can be send (from within HQ) to a group of dm Servers and the outputs of each instance is sent back and made available in Hyperic
    c) resolution conflicts/ problems – as mentioned above – can be seen within Hyperic (Actually I'm not too sure whether this can not already be realized with the current version of Hyperic)

    Thanks in advance and please keep up the good work!

    Regards
    Alex


  9. @Sudheer

    Have you tried the packages command, by the sounds of it this should give you most of what you want. If not could you give me some more detail? As for the tree structure for uses conflicts, I can see how this would help. I have raised a Jira for it so it gets discussed in the team. Users conflicts are hard to resolve, we will need to be careful with any interface we create for their resolution. (https://issuetracker.springsource.com/browse/DMS-1765)

    @Alex

    We are making some enhancements to the services information in our current sprint which should help you a lot. I'm going to ask someone working on the Hyperic integration to comment on your 2nd point.

    Thanks to both of you for your comments.


  10. Based on Felix or Karaf I see…

    Very good, I always liked their commandline interfaces better anyway.


  11. @Mike

    Well, the dm Shell is our own implementation, any similarities are coincidental. I'm glad you like it though.

    Chris.


  12. @Chris:

    Does the service property based discovery actually work with services that are not provided as part of the kernel? How can I make the shell aware of a command provided as service in the user realm?

    Cheers,
    Denis


  13. Hi Denis,

    The shell has had a bit of a rewrite since this blog post went out. The Shell is run in the Kernel region and not available to the user region. Although we do not support the addition of new commands I don't think it would be very hard. From your comment I'm guessing you've had a look at the code. All you would need to do is deploy a normal bundle that publishes commands in the same way that the other ones do. Then edit the config files to allow your service to be mapped up to the kernel region. I think you would only need to add your service to the 'serviceExports' list in the 'com.springsource.kernel.userregion.properties' file. I'd be interested to know how you get on as we haven't tried this with the new shell system.

    Thanks, Chris.


  14. Hi Chris,

    thanks. That exactly what I did. Just thought there might be a way that works without customizing the DM server config.
    Anyway, for the record, here the detailed description:

    - I created a tagging interface "UserCommand" that marks all my command implementations in the user region and has no methods.

    To bridge the services of the user region into the kernel, the following changes are made to the DM Server config file com.springsource.kernel.userregion.properties:
    * Add to packageImports: com.springsource.kernel.shell;version="[2.0.0,2.0.1)" to make the Command annotation available in the user region.
    * Add to serviceExports: ".UserCommand" to bridge all Services that implement UserCommand to the kernel

    So far, it works like a charm. To use CommandCompleter as well one just needs to add this interface to serviceExports as well. I did not yet used the ServiceRegistry based command resolver, just the one based on the Command annotation.

    I could not find a way to bridge services based on annotations. May I suggest to include a tagging interface in com.springsource.shell? This way, this procedure would be less of a hack. :-)

    Cheers, Denis


  15. Great, thanks for posting that Dennis.

    As I say we never looked in to how people would extend the Shell. We could make it a little easier I agree but there is nothing wrong with editing the config. We put it out in text files for just that reason :)
    I like the idea of a separate annotation for User Commands.

    I'd stick with the Command annotation as well.

2 trackbacks

Leave a Reply