XPC service(s) to handle multiple loadable bundles in a sandbox app - cocoa

I have a sandbox app which accepts third-party made plugins, multiple plugins at the same time could be connected. I'd like to use XPC service(s) to create another layer of security for those bundles and just in case if one of them crashes I'd like to continue using others without this one.
I am using NSXPCConnection, but the problem is I cannot create multiple instances of this thing at the same time. All instances mess up with each other. I don't want one service instance to handle all the bundles, because if I have a problem with one than I would have to restart whole thing. And I don't want to create a bunch of service duplicates in the project just to do the same thing by using the different service name.
So maybe there is another way to do this, maybe even there is a proper way, please help

Related

What are my alternatives for managing RabbitMQ channel changes as a part of CD process

I am looking for alternatives for managing my RabbitMQ setup, same as i manage my RDBMS with liquibase/flyway or mongo with mongeez.
After looking around a bit I havent found any resources on it as much (Which gets me thinking on how companies actually do it).
I read thread that talked about each component creating the channels that it needs to its either there or it will be created in runtime when needed.
Other then that i haven't found any mention of a request like mine, am i looking at this the wrong way?
We manage it the following way. It's not a clean straight forward solution, but it works.
Installation, update and base-configuration of RabbitMQ is done via an ansible role.
Creation, update and deletion of virtual hosts, users and access permissions is done via a second ansible role
Management, i.e. create, update and delete of queues and exchanges is done from within the application
With this setup we were able to provide a multi tenant configuration and efficiently manage several installations in several stages.

Strategies for making platform level decisions within a bundle

I have a requirement where, if one bundle fails to start because of some internal state issue, the entire application should not be running and thus the platform should be shutdown (bundleCtx.getBundle(0).stop()).
Because of OSGi's nice modularity and so on, other bundles might've started up just fine.
It feels kinda wrong for bundles to be calling bundleCtx.getBundle(0).stop() (or System.exit(nn) if a BundleException occurs) in different places.
Is there a common way to implement this? One way may be Declarative Services, but those are only notified when a given component starts, right? It cannot tell if something has failed (AFAIK).
Ah, here is one possibility I just stumbled upon.
I have a bootstrap bundle which is responsible for starting all of the other bundles in my app. It does this with START_TRANSIENT.
I could put logic into this bundle to do certain things depending on which bundle failed.
So one idea would be to have one bundle that checks if all needed services and bundles come up. It can then stop the framework if one or more services are missing or if a bundle does not start. This would allow to centralize the checking logic at one place.

What is the best approach for the "lock file" pattern in spring applications?

I am looking for a way to implement the "lock file" pattern in a spring application. What I want to prevent is multiple copies of the same spring application from starting using the same resources ( e.g. database ) at the same time. I know that in unix systems it is common for an app to create a file called ".lock" as it is starting up and refuse to start if that file already exists. This prevents multiple instances from running on the same server. I have some ideas about applying this pattern to the problem of multiple spring applications running against the same database but I want to know if there is anything that has been developed specifically for this problem that is more general or built in to the framework.
I was looking for such a solution also, and could not find any.
Implementation should be easy,
check/create the lock file on startup
remove it with a JVM shutdown hook (so it gets removed even if the app crashes)
If the JVM crashes (e.g. out of memory) the file will not be removed, I think there is no way to avoid that.

Alternatives to XPC Service

I am trying to port Wine 1.7.13 to modern Cocoa. I am considering running Windows binaries in an XPC service’s process, for security isolation and crash-proofing. However, there is one problem: To the best of my knowledge, XPC services are singletons. Only one XPC service process is allowed to be running at a time. This is a problem because, if I use threads to enable multiple Windows binaries to run at once, a segfault or other hard crash in one Windows binary would cause all the other binaries to crash with it.
As mentioned here, it is generally understood that the above assertion is true. If that is so, it would seem that I cannot implement this sort of isolation within a single XPC service process.
My other alternative is to use sandbox inheritance (having the GUI application fork and using more traditional IPC to have the Windows processes talk to each other) instead of an XPC service. What are the pros and cons of using that instead of an XPC service? I understand that processes that inherit their parent’s sandbox does not get to have its own entitlements. What other drawbacks are there?
I also understand that Apple discourages the use of sandbox inheritance in favor of XPC, but it is still an available design decision. They must have kept it around for a reason. Would a sandboxed Mac App Store app be able to use sandbox inheritance in this fashion?
I am going through the same decision. I had my heart set on XPC services, but upon discovering that there would be a single XPC Service with multiple connections, I cannot use them (my XPC Service will use plug-ins provided by third-parties so I want to keep them apart, and also the XPC Service will use libraries that might not clean-up properly, so I want to be able to dispose of them while keeping the UI stable - well I shouldn't have to justify this - I want one-process-per-job and that's that).
I am considering the normal sub-process model using posix_spawn() (I think this behaves better than fork() WRT to Sandboxing), CocoaAsyncSocket for the comms. I am going to see if I can replace the use of TCP/IP in CocoaAsynSocket with UNIX sockets to speed-up up comms (with the intent of contributing it back to the project if this works out). (UPDATE: this has already been done, some time ago by github user #jdiehl. See his socketUN branch and the discussion in issue #88 of the upstream repo).
For data marshalling I will use Google Protocol Buffers (UPDATE #2: Nope; not worth the hassle when NSKeyedArchiver and NSKeyedUnarchiver provide everything required out-of-the box. They may not provide data as packed as Google Protocol Buffers, but they 1) Don't require writing and maintaining, 2) Allow any class to participate by implementing the NSCoding protocol, and 3) Don't have to solve the issue of cross-platform data exchange.
The only possible disadvantage I can see is I don't know if file bookmarks can be passed to the subprocess and used (i.e. the UI opens a file or has a file dragged to it and wants to give access to the file to the worker process). I will update this answer with whatever I learn. (FINAL UPDATE: Passing the URL bookmark across the UNIX domain socket works fine, and the bookmark doesn't even need to be a security-scoped bookmark for this to work. There are no more impediments to this alternative to XPC).
Your assertion is incorrect about sub-processes not having their own entitlements; they do and are embedded into the executable and it must have "inherits sandbox" set for the sub-process to work correctly.
And the end-of-the-day the one-xpc-service-per-app is a show stopper so you have no choice but to find an alternative.

How to provision OSGi services per client

We are developing a web-application (lets call it an image bank) for which we have identified the following needs:
The application caters customers which consist of a set of users.
A new customer can be created dynamically and a customer manages it's users
Customers have different feature sets which can be changed dynamically
Customers can develop their own features and have them deployed.
The application is homogeneous and has a current version, but version lifting of customers can still be handled individually.
The application should be managed as a whole and customers share the resources which should be easy to scale.
Question: Should we build this on a standard OSGi framework or would we be better of using one of the emerging application frameworks (Virgo, Aries or upcoming OSGi standard)?
More background and some initial thoughts:
We're building a web-app which we envision will soon have hundreds of customers (companies) with hundreds of users each (employees), otherwise why bother ;). We want to make it modular hence OSGi. In the future customers themselves might develop and plugin components to their application so we need customer isolation. We also might want different customers to get different feature sets.
What's the "correct" way to provide different service implementations to different clients of an application when different clients share the same bundles?
We could use the app-server approach (we've looked at Virgo) and load each bundle once for each customer into their own "app". However it doesn't feel like embracing OSGi. We're not hosting a multitude of applications, 99% of the services will share the same impl. for all customers. Also we want to manage (configure, monitor etc.) the application as one.
Each service could be registered (properly configured) once for each customer along with some "customer-token" property. It's a bit messy and would have to be handled with an extender pattern or perhaps a ManagedServiceFactory? Also before registering a service for customer A one will need to acquire the A-version of each of it's dependencies.
The "current" customer will be known to each request and can be bound to the thread. It's a bit of a mess having to supply a customer-token each time you search for a service. It makes it hard to use component frameworks like blueprint. To get around the problem we could use service hooks to proxy each registered service type and let the proxy dispatch to the right instance according to current customer (thread).
Beginning our whole OSGi experience by implementing the workaround (hack?) above really feels like an indication we're on the wrong path. So what should we do? Go back to Virgo? Try something similar to what's outlined above? Something completely different?!
ps. Thanks for reading all the way down here! ;)
There are a couple of aspects to a solution:
First of all, you need to find a way to configure the different customers you have. Building a solution on top of ConfigurationAdmin makes sense here, because then you can leverage the existing OSGi standard as much as possible. The reason you might want to build something on top is that ConfigurationAdmin allows you to configure each individual service, but you might want to add a layer on top so you can more conveniently configure your whole application (the assembly of bundles) in one go. Such a configuration can then be translated into the individual configurations of the services.
Adding a property to services that have customer specific implementations makes a lot of sense. You can set them up using a ManagedServiceFactory, and the property makes it easy to lookup the service for the right customer using a filter. You can even define a fallback scenario where you either look for a customer specific service, or a generic one (because not all services will probably be customer specific). Since you need to explicitly add such filters to your dependencies, I'd recommend taking an existing dependency management solution and extending it for your specific use case so dependencies automatically add the right customer specific filters without you having to specify that by hand. I realize I might have to go into more detail here, just let me know...
The next question then is, how to keep track of the customer "context" within your application. Traditionally there are only a few options here, with a thread local context being the most used one. Binding threads to customers does tend to limit you in terms of implementation options though, as in general it probably means you have to prohibit developers from creating threads themselves, and it's hard to off-load certain tasks to pools of worker threads. It gets even worse if you ever decide to use Remote Services as that means you will completely loose the context.
So, for passing on the customer identification from one component to another, I personally prefer a solution where:
As soon as the request comes in (for example in your HTTP servlet) somehow determine the customer ID.
Explicitly pass on that ID down the chain of service dependencies.
Only use solutions like the use of thread locals within the borders of a single bundle, if for example you're using a third party library inside your bundle that needs this to keep track of the customer.
I've been thinking about this same issue (I think) for some time now, and would like your opinions on the following analogy.
Consider a series of web application where you provide access control using a single sign-on (SSO) infrastructure. The user authenticates once using the SSO-server, and - when a request comes in - the target web application asks the SSO server whether the user is (still) authenticated and determines itself if the user is authorized. The authorization information might also be provided by the SSO server as well.
Now think of your application bundles as mini-applications. Although they're not web applications, would it still not make sense to have some sort of SSO bundle using SSO techniques to do authentication and to provide authorization information? Every application bundle would have to be developed or configured to use the SSO bundle to validate the authentication (SSO token), and validate authorization by asking the SSO bundle if the user is allowed to access this application bundle.
The SSO bundle maintains some sort of session repository, and also provides user properties, e.g. information to identify the data repository (of some sort) of this user. This way you also wouldn't pass trough a (meaningful) "customer service token", but rather a cryptic SSO-token that is supplied and managed by the SSO bundle.
Please not that Virgo is an OSGi container based on Equinox, so if you don't want to use some Virgo-specific feature, you don't have to. However, you'll get lots of benefits if you do use Virgo, even for a basic OSGi application. It sounds, though, like you want web support, which comes out of the box with Virgo web server and will save you the trouble of cobbling it together yourself.
Full disclosure: I lead the Virgo project.

Resources