How to Use Cargo Repositories in Artifactory

How to Use Cargo Repositories in Artifactory

For five years running, Rust has taken the top spot in Stackoverflow’s survey of most loved programming languages. Seen by many as the next step after C/C++, the language is fast becoming embraced by embedded device developers and as a robust system for IoT.

At JFrog, we took notice and are eager to welcome Rust developers to the empowerment of robust binaries management and how it contributes to continuous integration. We’ve added Cargo, the package management system for the Rust programming language, to the long list of repository types we support in Artifactory.

What has Rust got that over 86% of developers gave it an enthusiastic thumbs up? And how can you use Cargo repositories in Artifactory to accelerate your software development lifecycle?

Why Rust?

Mozilla Research describes Rust as a “systems programming language that focuses on speed, memory safety, and parallelism.” These key features help support that vision:

  • Automatic Garbage Collection – Rust shields against resource leak bugs by enforcing RAII (Resource Acquisition Is Initialization), freeing resources whenever the object that owns them goes out of scope.
  • Strong Concurrency Support – Rust is designed to handle concurrent, multi-threaded programming safely and efficiently. Strong types, along with Send and Sync traits help ensure synchronized, thread-safe operation, along with a standard thread library that empowers Rust code to run in parallel.
  • Safety Checks – The Rust compiler enforces memory safety and other checks to help ensure clean, robust code.
  • Reusable Packages – Rust provides a powerful system that enables developers to create reusable units of code organized as crates that can be shared privately within a project, or publicly with others.
  • Dependency Management – The Cargo package manager for Rust provides facilities for downloading and compiling package dependencies. 

These features, along with other popular syntactical features (such as complex data types, mutable/immutable borrowing, and recoverable/unrecoverable error handling) delight developers.

Remote Cargo Repositories

The friendly and active Rust community maintains the crates.io package registry for distributing open-source packages. As a Rust programmer, you’ll rely on this growing public library for most of the core services of your applications.

To help assure uninterrupted speed and consistency of your Rust builds across teams, use an Artifactory remote repository to proxy crates.io.

A remote repository in Artifactory serves as a caching proxy for a repository or registry managed at a remote URL. There will be no difference between the contents of the remote repo and the native source.

When you put this best DevOps practice to work, you and your team gain:

  • Locality for speed — The proxy pulls and keeps the packages you use frequently into the compute environment where your builds happen, whether in the cloud or on-prem, minimizing network latency.
  • Connection protection — Your crates.io proxy remains available even when the crates.io server isn’t due to a poor or interrupted connection, or if the remote server itself suffers an outage
  • Immutability enforcement — Once a package version is in the proxy, it’s unchanging and the same in every build that uses it. This guards against anything sneaking into your builds through an improper forced push into the public repo. 

It’s easy to set up a remote repository proxy for crates.io:

  1. Create a new Cargo remote repository in Artifactory
    Create a new Cargo remote repository in Artifactory
  2. Name the remote repository and assign the URL for crates.io
    Name the remote repository and assign the URL for crates.io
  3. In your application package’s config.toml manifest file, configure the [registry] default to redirect to the Artifactory remote repo instead of crates.io. (See “Set Me Up” in the Artifact Browser for instructions.)

    Your remote repository proxy will be read-only, which is as it should be for most daily work of pulling in open-source dependencies for your builds. If you need to publish to crates.io, you can define a name for it under [registries] and  use it with the --registry option when you do. (Just make sure your package.publish key in the manifest also specifies that registry name to enable publishing to it.

    # Makes artifactory the default registry and saves passing --registry parameter
    [registry]
    default = "art-crates-remote"
    
    [registries]
    # Remote repository proxy in Artifactory (read-only)
    art-crates-remote index = { index = "https://artprod.mycompany/artifactory/git/cargo-remote.git" }
    
    # Optional, use with --registry to publish to crates.io 
    crates-io = { index = "https://github.com/rust-lang/crates.io-index" }

Local Cargo Repositories

For the crates that you will create and share only within your team or department, you should maintain private Cargo registries. In Artifactory, you can create as many registries as you need through local Cargo repositories.

For example, a team working on “Project X” might set up and use a local cargo repo:

  1. Create the local Cargo repository in Artifactory named “cargo-local-projectx”.
  2. In the ~/.cargo/Config.toml file, configure a registries definition for the local repo.
    [registries]
    projectx = { index = "https://artprod.mycompany/artifactory/git/cargo-local_projectx.git" }
     
    [package]
    publish = "projectx"

    In Cargo.toml specify publishing to the new registry by setting package.publish:

    [package]
    ...
    publish = ["projectx"]
    ...
  3. When you publish your crate to the local repo in Artifactory through cargo publish, specify the --registry option.
    $ crate publish --registry "projectx"
  4. To use the crate now in the local repository as a dependency in your Project X application source code, specify the registry along with the version.
    [dependencies]
    some-crate = { version = "1.0", registry = "projectx" }

Conclusion

With strategic use of both remote and local repositories for Cargo in Artifactory, you’ll be putting to work some of the most important best practices for your SDLC to enable DevOps success. You can ensure consistency across all your Rust developer teams for dependencies and packages, with native Cargo support that doesn’t get in their way. And you can also govern access across teams with Artifactory’s fine-grained permissions system.

Try Artifactory’s Cargo repositories for yourself and see! You can start putting these methods into practice with a free JFrog cloud account!

Related Resources: