The Juju "core" Package


The purpose of this post is to tease out consensus on the purpose of the core package in Juju.

I have a patch up to add units to the new model cache. The logic for the cache resides in core and there is a worker that maintains the cache via a multi-watcher.

Multi-watcher deltas for units include slices of Port and PortRange. The multi-watcher DTOs for these types need to be converted to network.Port and network.PortRange, which would violate dependency-free requirement of the core package, necessitating the import of network.

I began what will be a migration of network to, but following some discussions I got to thinking if we move things into core because things in core need them, we’ll just end up moving more and more into core, defeating its purpose. Note that the validity of moving at least parts of network into core is not being questioned; it is just the example at hand.

A lot of what is in core makes intuitive sense:

  • Interfaces that can be imported without dragging in their implementation packages.
  • Types, constants and validations that apply cross-package.
  • Other fundamental concepts that are axiomatic to Juju and do not need other Juju packages.

But there are other sub-packages in core that include more “wholesale” implementations of parts of Juju - the model cache being one, Raft leases another.

So at this point the questions are:

  • What is the stated purpose of the core package?
  • By what criteria should something reside in core?
  • Are there things now under core that should not be there?


The primary purpose of the core package is for types and business logic that is provider independent.

A key indicator as an example is the bridging code in the network package that has a dependency on the database state package. Clearly this isn’t a core function.

Nothing in core should use the JujuConnSuite, or even StateSuite for testing.