-
-
Notifications
You must be signed in to change notification settings - Fork 579
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
Pantheon Provider plugin #345
Conversation
2c27601
to
b9985fc
Compare
This has been rebased and is "test drive" worthy at this point. |
Architectural notesThere are a couple decisions here which I'm only somewhat sure I like. I figured I may as well call them out.
Additional musings
|
Testing #345 ReferencePreparation
Testing
Spitballing
|
Overall, my reaction is very positive. There is a bit of polish and/or a bit of guidance that can be provided to assist. Example, running the import without a There is also a bigger need (which I can understand why we would wait for feedback at the technical level first) of getting information ready for our documentation. That in no way impacts the technical review and some of that is included in this PR summary. However, we'd want to make sure this doesn't get neglected. |
One other error that popped up. When running |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As stated in #345 (comment) and follow-up comments. Overall this is very positive and moving in the right direction. There is a few use cases to address and areas where additional documentation/instructions can be helpful.
I made the following updates based on feedback from @rickmanelius
I did NOT do the following:
I think prompting works best to avoid flag/argument soup, such as in |
I'm mid review on the updates. One thing I think that has been surfaced before and I feel strongly will bite us in the ass is that "ddev config-pantheon" and "ddev config pantheon" differ by only a hyphen and yet do completely different things. We discussed things like "auth" or "connection" for the global config. See notes here #216 (comment). |
When running |
So yeah. The latest changes are very helpful. Still a nit about the global config name and the string error cropped up. Beyond that, I think from the end-user perspective this is worthy of a merge, but it does need a technical review and docs. I'm cool with splitting out documentation as a second PR if it would be a big lift (trying to keep commits smaller so that we don't keep long standing WIP). |
Agreed. I do hate I'd vote to move it to |
I'm good with |
As discussed in Slack, I'll take a first stab at the documentation. |
Documentation is being addressed here #369 and is in a "Needs Review" status. |
@rfay @tannerjfco When you get a chance, I would love to get reviews on this item to get to a consolidated punch list. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a first pass through the code. Mostly smaller cleanup stuff and some questions. I'm intending to take this for a test drive and deeper look tomorrow.
cmd/ddev/cmd/config.go
Outdated
provider := "" | ||
|
||
if len(args) > 1 { | ||
log.Fatal("Invalid argument detected. Please use 'ddev config' or 'ddev config [provider]' to config a site.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
util.Failed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"... to configure a site"
cmd/ddev/cmd/import.go
Outdated
var ImportCmd = &cobra.Command{ | ||
Use: "import", | ||
Short: "Import files and database using a configured provider plugin.", | ||
Long: ``, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs long help text.
cmd/ddev/cmd/import.go
Outdated
|
||
client := dockerutil.GetDockerClient() | ||
|
||
err := dockerutil.EnsureNetwork(client, netName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not clear on the intent of this in the PreRun.
util.Failed() would be preferable for error message to the user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is repeated all over the place, my next commit refactors into a single dockerNetworkPreRun()
function for consistency. It also changes the error reporting to use util.Failed()
pkg/ddevapp/config.go
Outdated
if err != nil { | ||
return err | ||
// Create an empty provider.env file to make docker-compose happy. | ||
_, err := os.Create(c.GetPath("provider.env")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we still need to close an empty file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you get an empty file regardless of whether you're using pantheon? what will user be expected to do with the empty file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will get an empty provider.env
file regardless of whether you are using pantheon or not. Otherwise, docker-compose will throw an error when using the env_file
directive. An empty provider.env is now created alongside the docker-compose.yaml, so the user can commit it or ignore it as they choose.
I don't love this, but we need a way to conditionally include environment vars. Open to other suggestions on how to achieve it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative would be to write a docker-compose.pantheon.yaml that sets the environment variables (or adds an env_file directive). This could potentially be a file managed by ddev.
@@ -0,0 +1,46 @@ | |||
package ddevapp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be useful/appropriate to use this no-op default as a form of documentation? I feel like it could be handy to explain the intent for each method, maybe even some basic pseudo code examples.
} | ||
|
||
if p.Environment == "" { | ||
p.Environment = "dev" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"live" seems like the most appropriate default, but i suppose with pantheon that doesn't exist until a site is close to done (and a credit card has been provided).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! I chose this as the default for that very reason. Dev is the first environment created by default on pantheon, and as such feels like the most consistently available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think dev is the right default in every case
keys = append(keys, k) | ||
} | ||
fmt.Println("\n\t- " + strings.Join(keys, "\n\t- ") + "\n") | ||
var environmentPrompt = "Type the name to select an environment to import from" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about numbered options for this prompt?
pkg/ddevapp/providerPantheon.go
Outdated
// If we can't read a previous session fall back to using the API token. | ||
apiToken := os.Getenv("PANTHEON_API_TOKEN") | ||
if apiToken == "" { | ||
log.Fatal("No saved session could be found and the environment variable PANTHEON_API_TOKEN is not set. Please use ddev config-pantheon or set a PANTHEON_API_TOKEN. https://pantheon.io/docs/machine-tokens/ provides instructions on creating a token.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
util.Failed
pkg/plugins/platform/local.go
Outdated
if err != nil { | ||
return err | ||
} | ||
err := l.AppConfig.WriteDockerComposeConfig() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we going to 'own' the compose file with this? We may want to consider using the file signature solution randy implemented here if so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope! the write is still conditional, the logic was just moved inside the function.
@@ -30,9 +32,20 @@ func DownloadFile(filepath string, url string) (err error) { | |||
if resp.StatusCode != http.StatusOK { | |||
return fmt.Errorf("download link %s returned wrong status code: got %v want %v", url, resp.StatusCode, http.StatusOK) | |||
} | |||
reader := resp.Body | |||
if progressBar { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shiny!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed! I felt like a progress bar was a must, as some archives might be quite large, and offering no visual feedback during a 5 gig download seems like a non-starter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round review of test drive:
- Yay, things worked great!
- Is it worth peeking in ~/.terminus/cache/tokens to get the token with config-pantheon? Or could we just use that cache instead of creating .ddev/pantheonconfig.json?
- I really can't go with competing
ddev config pantheon
andddev config-pantheon
commands. Pretty sure they just frustrate customers and will be the an object of frustration. I think I've seen this discussed already. Looks like there's a plan to use authenticate-pantheon as the command? - I wasn't clear about what the starting situation was. Should I be doing this in an empty directory? In a created ddev directory? Rick's docs say that I need to git clone the upstream; that seems like more work that we'd expect people to undertake, but they are going to need a clone at some point.
- Error "You must provide a Pantheon machine token, e.g.
ddev config-pantheon [token]
." should not include markdown backticks - it's plain text. - Why does it go through the whole start (container creation) process just to do it again after the import?
ddev import
seems like a problematic addition. I think it will be confusing.- Don't forget to add post-import capabilities after pre/post goes in.
- I'm not actually all that comfortable yet with what we're doing with settings.php, will have to review the nginx-php-fpm PR and think through other possibilities.
I'l review the code and the fpm PR a little later.
We could probably peek if we wanted. Terminus does support multiple logins in that folder, though, which could raise some concerns over which we use (just randomly pick one? try multiple to see if they are active? what if it's an old account or an expired token?). We'd need to decide what the behavior should be. Personally, I'm fairly against writing anything to the terminus token cache.
Agreed.
Containers need to be started to perform the additional import. After the import is done, we need to inject DB credentials and other settings via environment vars (since settings files are committed on pantheon). Doing this requires us writing a provider.env (or perhaps a docker-compose.pantheon.yaml as Tanner suggested earlier) and a restart of the site for those variables to take effect.
Totally open to alternative suggestions. We could re-use import-db and import-files and break it into a two-step process, but I was worried about overloading those commands with vastly different behaviors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs some work for WordPress sites. Imports seem to be successful, but site produces 500 error after start due to invalid configuration file (for this environment).
It seems like we should be able to set the PANTHEON_ENVIRONMENT env var to have the credentials read from env vars. We'll additionally need to define these variables:
AUTH_KEY
SECURE_AUTH_KEY
LOGGED_IN_KEY
NONCE_KEY
AUTH_SALT
SECURE_AUTH_SALT
LOGGED_IN_SALT
NONCE_SALT
We'll also need to ensure a search-replace happens after import.
If I manually configure wp-config.php and perform a search-replace, the wordpress site seems to work as expected from there.
I was not testing w/ the right web tag. This feedback is invalid.
ad4a048
to
006ebc4
Compare
Do we need to read values from the imported database (or some other downloaded asset) in order to set these env vars? Just wondering if we can set these vars before the import occurs, so that we don't have to restart.
It makes sense to me to re-use the separated import commands. Dealing with locally stored assets, their functionality isn't all that impressive, but I think they become quite a bit more impressive and useful handling syncing from upstream environments. I also think developers should be able to import just the database or files, regardless of provider. It's not uncommon for developers to only want a db dump, and to use something like stage_file_proxy to avoid pulling files (this becomes necessity for sites w/ a large volume of assets). I don't feel like it would be unreasonable for these to accept provider as argument, e.g. |
…ing the default provider
Per @beeradb I rebased this for testing purposes. |
@beeradb There's no sign that the TestPantheon* tests have been running during circle tests (or during mine on Windows). I don't know why this is. I think it's important to resolve before pull. See https://circleci.com/gh/drud/ddev/1348 for example. Edit: It turns out that the tests in config_test.go are also being ignored. |
With this last test run passing and @rfay giving the green light on windows, it's time to hit the button! |
What happened (or feature request):
As per #216 we need pantheon integration. This PR introduces the integration.
At this point, it is feature complete enough to take it for a test drive.
There are three new commands which will be needed:
ddev config-pantheon [token]
sets global configuration for talking to the pantheon API. Please see https://pantheon.io/docs/machine-tokens/ for documentation on creating a machine token.ddev config pantheon
extends standard ddev config to account for pantheon specific data.ddev import
imports from a provider. It prints an error if no external provider has been configured.There are also two new files which get added to the
.ddev
folder:How to reproduce it (as minimally and precisely as possible):
ddev config pantheon
from the git root directory. Follow configuration prompts.ddev import
Related source links or issues:
#216 is the parent issue.