Skip to content

Add support for Netrc for Downloader #2833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 3, 2020
Merged

Conversation

sstadelman
Copy link
Contributor

@sstadelman sstadelman commented Jul 28, 2020

Implemented handling for netrc files. Matches connection settings for binary artifact host, and returns Basic authentication header to be appended to internal URLRequest of the Downloader. Will resolve Supporting basic auth for non-git binary dependency hosts.

Netrc parser based on Carthage implementation and tests, and migrated to regex for flexibility.

Features supported

  • Parse Netrc string text: single and multi-line
  • Match machine, login, password key values
  • Ignore comments
  • Ignore account and macdef entries (relevant only to ftp remotes)
  • Accept any order of login, password, account key values
  • Match default connection settings.
  • Validates single instance of default connection setting, and that default connection setting is last entry
  • Checks for netrc file in NSHomeDirectory()/.netrc by default
  • Workspace supports custom netrcFilePath parameter

Sequence Flow (including SPM)

Screen Shot 2020-07-18 at 12 13 19 AM

In SPM, a netrc file absolute path is resolved during (3) getActiveWorkspace() call of run() procedure, from optional command argument (1) or NSHomeDirectory()/.netrc (4). Resolved absolute path is passed to initialized Workspace(5).

If binary artifacts should be updated, then the (7) download(...) operation attempts to load the netrc machine definitions from a file at the resolved netrcFilePath(8). The optional resulting Netrc instance is passed to the created FoundationDownloader for each artifact (11). The downloader attempts to match a credential in the list of the Netrc instance's Machine definitions for the artifact host (13). If matched, the base64-encoded <user>:<password> pair is set to the Authorization header for the respective URLRequest.

Notes

  1. The main question wrt API addition was: how to efficiently pass the netrc content to the Downloader protocol, which is lightweight by design. Though netrc is a common technique, it is not necessarily a universal solution--perhaps in the future we should also support application tokens, etc., which might similarly pollute the protocol. So, this implementation introduces the AuthorizationProviding interface, under which additional authentication techniques could in the future be added to the Workspace, and injected to the binary update process in Downloader implementations.
public protocol AuthorizationProviding {
    /// Optional `Authorization` header, likely added to `URLRequest`
    func authorization(for url: Foundation.URL) -> String?
}

Downloader is extended as follows:

/// The `Downloader` protocol abstract away the download of a file with a progress report.
public protocol Downloader {
    /**/
    /// Downloads a file and keeps the caller updated on the progress and completion.
    ///
    /// - Parameters:
    ///   - url: The `URL` to the file to download.
    ///   - destination: The `AbsolutePath` to download the file to.
    ///   - authorizationProvider: Optional provider supplying `Authorization` header to be added to `URLRequest`.
    ///   - progress: A closure to receive the download's progress as number of bytes.
    ///   - completion: A closure to be notifed of the completion of the download.
    func downloadFile(
        at url: Foundation.URL,
        to destination: AbsolutePath,
        withAuthorizationProvider authorizationProvider: AuthorizationProviding?,
        progress: @escaping Progress,
        completion: @escaping Completion
    )
}
  1. The netrc credential injection is added to FoundationDownloader. Other Downloaders should implement handling according to their requirements.
  2. Requires OSX 10.13. Will obligate swift-driver and swift-tools-support-core packages to raise minimum to 10.13 also. Discussed in thread.

@sstadelman
Copy link
Contributor Author

@neonichu depends on swiftlang/swift-driver#185.

@sstadelman
Copy link
Contributor Author

@swift-ci please test

@sstadelman
Copy link
Contributor Author

Please test with following PR:
swiftlang/swift-tools-support-core#88
swiftlang/swift-driver#185

@swift-ci Please test macOS platform

@sstadelman
Copy link
Contributor Author

@neonichu is there anything I can do to help get this in the queue? I've got a product release in October which might be dependent on it.

@sstadelman
Copy link
Contributor Author

Please test with following PR:
swiftlang/swift-tools-support-core#88
swiftlang/swift-driver#185

@swift-ci Please test

@sstadelman sstadelman changed the title [Ready for Review] Add support for Netrc for Downloader [Do not merge] Add support for Netrc for Downloader Aug 11, 2020
Copy link
Contributor

@neonichu neonichu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except for one comment. Thank you very much for the contribution, @sstadelman

usage: "Absolute path to netrc file for downloading binary target artifacts"),
to: { $0.netrcFilePath = $1.path })
}
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have the option always be present and emit an error if it is being used on non-macOS. It doesn't really matter right now since binaries aren't supported on non-macOS, but I think silently ignored options can be confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neonichu
Copy link
Contributor

Please test with following PR:
swiftlang/swift-tools-support-core#88
swiftlang/swift-driver#185

@swift-ci Please smoke test

@sstadelman
Copy link
Contributor Author

@neonichu made change requested, also synced changes from swift-tools-support-core #88

Since that is merged, and swift-driver PR is cancelled, can test/smoke-test directly.

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@neonichu
Copy link
Contributor

Sorry for the conflicts, but I needed to unblock the build in #2876 separately from this.

@sstadelman
Copy link
Contributor Author

@neonichu do you need me to clean up these conflicts?

@MaxDesiatov
Copy link
Contributor

Yes, please clean up the conflicts, I'll be able to trigger CI then.

@sstadelman sstadelman changed the title [Do not merge] Add support for Netrc for Downloader Add support for Netrc for Downloader Aug 19, 2020
@sstadelman
Copy link
Contributor Author

@MaxDesiatov resolved conflicts

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@sstadelman
Copy link
Contributor Author

@MaxDesiatov I see it passing on self-hosted linux. I guess there's an integration issue elsewhere.

@neonichu
Copy link
Contributor

Probably transient failures, let's try again.

@neonichu
Copy link
Contributor

@swift-ci please smoke test

2 similar comments
@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@neonichu
Copy link
Contributor

Sorry @sstadelman, I'm afraid that merging the swift-argument-parser PR has made this conflict yet again :/

@sstadelman
Copy link
Contributor Author

sstadelman commented Aug 27, 2020 via email

@sstadelman sstadelman force-pushed the master branch 2 times, most recently from 1b98c58 to 136b515 Compare August 28, 2020 05:25
@sstadelman
Copy link
Contributor Author

@neonichu gtg

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@MaxDesiatov
Copy link
Contributor

PackageToolTests.testNetrcFile is failing on Linux now.

@sstadelman
Copy link
Contributor Author

sstadelman commented Aug 31, 2020

I'm having trouble running in docker, or Xcode 11.6, due to missing @_spm tag. This isn't a problem in swift-tools-support-core. Is there a way to avoid these conflicts?

This is my current environment:

# TO LAUNCH DOCKER SWIFT ENV (from package root)
docker run --rm --privileged --interactive --tty --volume "$(pwd):/src" --workdir "/src" swift:latest

# FROM INSIDE DOCKER
apt-get update && apt-get upgrade
apt-get install libsqlite3-dev
swift test --enable-test-discovery --filter CommandTests.PackageToolTests

@neonichu sorry for a noob question, but I’m stuck getting my Linux environment up and running as configured above, since there seems to be a dependency in swift-driver on 5.3 features which are not available in Linux distribution. This has got me temporarily blocked. Is there any guidance you can share for the spm Linux environment setup, so I can get this thing free again?

@MaxDesiatov
Copy link
Contributor

MaxDesiatov commented Aug 31, 2020

Did you try using 5.3 nightly images?

swift:latest points to the latest stable version, not a 5.3 snapshot, which seems to be required to build this PR.

@sstadelman
Copy link
Contributor Author

@MaxDesiatov good to go!

for posterity, here's the linux docker setup:

# TO LAUNCH DOCKER SWIFT ENV (from package root)
docker pull swiftlang/swift:nightly-5.3-bionic
docker run --rm --privileged --interactive --tty --volume "$(pwd):/src" --workdir "/src" swiftlang/swift:nightly-5.3-bionic

# FROM INSIDE DOCKER
apt-get update && apt-get upgrade
apt-get install libsqlite3-dev
apt-get install libncurses5-dev
swift test --enable-test-discovery --filter CommandsTests.PackageToolTests

@MaxDesiatov
Copy link
Contributor

@swift-ci please smoke test

@MaxDesiatov
Copy link
Contributor

@sstadelman thank you, all passes now.

@neonichu would you be able to have yet another look and merge if everything's good to go?

@neonichu
Copy link
Contributor

neonichu commented Sep 3, 2020

Thanks @sstadelman, this is great.

@neonichu neonichu merged commit 7387fc7 into swiftlang:master Sep 3, 2020
@sstadelman
Copy link
Contributor Author

Thanks again @neonichu and @MaxDesiatov, really appreciated your help and attention on this feature! 🍻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants