Skip to content
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

Create faas-cli add-template --url <URL> command #87

Closed
wants to merge 2 commits into from

Conversation

ericstoekl
Copy link
Contributor

@ericstoekl ericstoekl commented Sep 8, 2017

  1. Create faas-cli add-template --url <URL> command
  2. Add template.yml files for each language in the ./template dir.
  3. Read fProcess from ./template/ in deploy command, instead of using hard-coded value
  4. Adds mock-server test

Description

Adds the addTemplate command and a basic test for it. Changes the way that fProcess command is acquired: from a hard-coded value in proxy/deploy.go to a new YAML file in each language-specific dir in the template/ dir, for example template/csharp/template.yml.

Motivation and Context

How Has This Been Tested?

Tests added in addTemplate_test.go

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I've read the CONTRIBUTION guide
  • I have signed-off my commits with git commit -s
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@alexellis
Copy link
Member

alexellis commented Sep 8, 2017 via email

@ericstoekl
Copy link
Contributor Author

Updated file names, improved help for add-templates command

@alexellis
Copy link
Member

For reference let's update the description of this PR with the naming "add-template".

@ericstoekl ericstoekl changed the title Create faas-cli addTemplate --URL <URL> command Create faas-cli add-template --url <URL> command Sep 11, 2017
URL = strings.TrimRight(URL, "/")
URL = URL + "/archive/master.zip"

err := os.Setenv("templateUrl", URL)
Copy link
Member

Choose a reason for hiding this comment

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

Is there a way to avoid passing the URL via environmental variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. I can change fetchTemplates() in fetch_temlates.go to accept a param of the custom URL.

Copy link
Contributor

Choose a reason for hiding this comment

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

The updated version no longer uses env var.

@ericstoekl
Copy link
Contributor Author

Question about this PR: should I add some logic to scan through the repository that is passed in to search for the template dir? Or should we look for third party templates in the root path of a repo? Currently fetchTemplates() only looks for the template dir in the faas-cli-master/ directory, because as the code is written right now, it only expects to be grabbing a template dir from the alexellis/faas-cli repo. The implication of this is that the repository containing 3rd party templates needs to be named faas-cli. We could have a 'custom URL' flag that fetchTemplates() takes to tell that the repo may be named anything. Or maybe if a custom URL is passed into fetchTemplates(), it just uses whatever repo name the URL points to.

https://github.com/alexellis/faas-cli/blob/3a2e81471c69275571d71f84c158bb787fb1ad7b/commands/fetch_templates.go#L31

@ghost
Copy link

ghost commented Sep 17, 2017

Thank you for your contribution. I've just checked and your commit doesn't appear to be signed-off.
That's something we need before your Pull Request can be merged. Please see our contributing guide.

@ghost ghost added the no-dco label Sep 17, 2017
@ghost ghost removed the no-dco label Sep 18, 2017
@ericstoekl
Copy link
Contributor Author

ericstoekl commented Sep 18, 2017

Thanks to @itscaro for huge help with this update. This update now supercedes #66. In this change the templateUrl environment variable usage is no longer possible.

@alexellis
Copy link
Member

@ericstoekl what's remaining to get this in?

@itscaro
Copy link
Contributor

itscaro commented Sep 20, 2017

@alexellis It's ready to be merge ;-)

@ericstoekl
Copy link
Contributor Author

@alexellis , I agree with Minh-Quan, it looks ready for merging.

@alexellis
Copy link
Member

This branch has conflicts that must be resolved

@ghost
Copy link

ghost commented Sep 23, 2017

Thank you for your contribution. I've just checked and your commit doesn't appear to be signed-off.
That's something we need before your Pull Request can be merged. Please see our contributing guide.

@ghost ghost added the no-dco label Sep 23, 2017
@itscaro itscaro force-pushed the addTemplateCmd branch 4 times, most recently from 12b7ddb to a6ebcc9 Compare September 23, 2017 11:20
@ghost ghost removed the no-dco label Sep 23, 2017
@itscaro
Copy link
Contributor

itscaro commented Sep 23, 2017

@alexellis Conflicts are resolved 👍


templateURLSplit := strings.Split(templateURL, "/")
templateURLSplit = templateURLSplit[len(templateURLSplit)-4 : len(templateURLSplit)-2]
Copy link
Member

Choose a reason for hiding this comment

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

I don't like the magic numbers -4 -2

What's this doing? maybe break out a function and document the indexes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just to name the master.zip file as the name of the repository. It's not necessary so I'm removing it.

@@ -137,3 +184,34 @@ func createPath(relativePath string, perms os.FileMode) error {
err := os.MkdirAll(dir, perms)
return err
}

// canWriteLanguage tells whether the language can be processed or not
// if overwrite is activated, the directory template/language/ is removed before to keep it in sync
Copy link
Member

Choose a reason for hiding this comment

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

@rgee0 @johnmccabe I don't know if overwrite should delete anything. It should probably dump over the top. Not sure?

Copy link
Contributor

Choose a reason for hiding this comment

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

Delete is a strong action. I do think it important that the user knows exactly what the current state of their templates is and that they aren't able to 'accidentally' overwrite.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have updated it to no longer delete before --overwrite.

// if overwrite is activated, the directory template/language/ is removed before to keep it in sync
func canWriteLanguage(language string, overwrite bool) bool {

if len(language) > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

I'm struggling to read/decipher this function - think it can be made simpler?

@@ -51,7 +51,7 @@ func runInvoke(cmd *cobra.Command, args []string) {
functionName = args[0]

if len(yamlFile) > 0 {
parsedServices, err := stack.ParseYAMLFile(yamlFile, regex, filter)
parsedServices, err := stack.ParseYAMLFileForStack(yamlFile, regex, filter)
Copy link
Member

Choose a reason for hiding this comment

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

Why ParseYAMLFileForStack vs ParseYAMLFile?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed this one back.

@@ -45,14 +45,20 @@ language or type in --list for a list of languages available.`,

func runNewFunction(cmd *cobra.Command, args []string) {
if list == true {
var available_templates string

if f, err := ioutil.ReadDir(templateDirectory); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

can we change f to something else please?

var available_templates string

if f, err := ioutil.ReadDir(templateDirectory); err != nil {
available_templates = "There is no available languages"
Copy link
Member

Choose a reason for hiding this comment

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

"No language templates were found. Please run 'faas-cli template pull'."

} else {
for _, file := range f {
if file.IsDir() {
available_templates += fmt.Sprintf("- %s\n", file.Name())
Copy link
Member

Choose a reason for hiding this comment

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

Build up an array in a separate function then return this - and have the formatting/printing separate.


if err := os.Chdir("../.."); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think I like this because it's cryptic. Please can you explain what's happening?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to execute these tests in faas-cli/commands/testdir/new_function directory, so we need to cd into it for the test to run, then cd back to the home directory afterwards (because we don't know what order the tests will execute in).

I've changed this to save the full directory path at the beginning of the function, then cd back into it instead of using the relative ../...

proxy/deploy.go Outdated
} else if language == "python3" {
fprocessTemplate = "python3 index.py"
} else {
fmt.Printf("Command to be invoked for function %s not found.\n", functionName)
Copy link
Member

Choose a reason for hiding this comment

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

When would this error fire off? There is no hard need to provide an fprocess at the deployment time. Some Dockerfiles will bake this in.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reverting this

stack/common.go Outdated
)

func ParseYAML(
file string,
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't read very well split over so many lines. How does it look on one line?

If there is a function being passed in - perhaps extract it to an interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What do you mean by extract to an interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually removing this entire file for now

stack/common.go Outdated
file string,
parseFunc func([]byte, ...string) (interface{}, error),
parseFuncArgs ...string,
) (interface{}, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Why does this return interface{}?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the interface may not be necessary for what we're doing here, I might refactor it to something more simple

Copy link
Contributor

Choose a reason for hiding this comment

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

It was for mutualise this function for parsing Stack & Language

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We will add this back in the next re-factoring PR


// iParseYAMLDataForLanguageTemplate parses YAML data into language template
// Use the alias ParseYAMLDataForLanguageTemplate
func iParseYAMLDataForLanguageTemplate(fileData []byte, args ...string) (interface{}, error) {
Copy link
Member

Choose a reason for hiding this comment

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

What's the "i"-prefix convention?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it returns an interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I'm going to try doing this without the interface approach.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually "i" was for "internal", I wanted not to expose it and use the public method to do the assertion on return type.

That's why ParseYAMLDataForLanguageTemplate calls iParseYAMLDataForLanguageTemplate.

This re-factoring is because I wanted to extract ParseYAMLFile to ParseYAML, since the part of parsing can be re-used for both LanguageTemplate & Stack

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am thinking we will add this re-factoring in a future PR, after this one is merged. The plan for this PR is to add minimal functionality.

stack/stack.go Outdated
if err != nil {
return nil, err
}
return object.(*Services), nil
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure why we need to use untyped interfaces?

Copy link
Member

@alexellis alexellis left a comment

Choose a reason for hiding this comment

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

Eric I think this will be a good addition to the CLI - it's been requested a number of times.

This PR touches a lot of files (at least 35) and involves both refactoring and new features. I have added some notes and questions.

i would like us to resolve as much as possible before merging.

@itscaro
Copy link
Contributor

itscaro commented Oct 28, 2017

@ericstoekl I add a verif when downloading an invalid url, the zip is removed if it's not valid.
The command prints out now the list of fetched languages, same as when it does not overwrite
I updated the guide too

@ericstoekl
Copy link
Contributor Author

Squashed the commits into 2 separate ones - First commit is everything before Alex's comments on 10/25, second commit is the changes to address those comments.

After the latest commit, the functionality is all the same, but the code has been changed in many places for simplification.

1. add-template updates
2. overwrite functionality
3. cacheLanguages for faster parsing, cache directory for zip file
4. tests for add-template, with overwrite option
5. test for PullTemplates function
1) Enable github repo ending in '/'
2) Allow 'faas-cli add-template' (no need to specify repo), picks default repo
3) More concise (shorter) summary of language templates applied/not applied
4) Change validTemplate to public facing IsValidTemplate function in stack package
5) Refactor BuildImage() function to use IsValidTemplate to check if language is valid (rather than hard-coded values)
6) Remove --lang option from invoke command (it is not used)

Signed-off-by: Eric Stoekl <ems5311@gmail.com>
Signed-off-by: Minh-Quan TRAN <account@itscaro.me>
2) Update guide with new links
3) Change to simplified version of
ParseYAMLFile/ParseYAMLFileForLanguageTemplate
4) simplify canWriteLanguage map, remove global variable usage
5) Don't print error message if no fprocess supplied (proxy/deploy.go)
6) Use absolute filepath for switching back to home directory after each new_function_test
7) Don't remove files before --overwrite

Signed-off-by: Eric Stoekl <ems5311@gmail.com>
Signed-off-by: Minh-Quan TRAN <account@itscaro.me>
@burtonr
Copy link
Contributor

burtonr commented Nov 3, 2017

Ran the tests on my machine and they all passed.
Pulled @ericstoekl Bash template from https://github.com/ericstoekl/faas-custom-templates and made a simple bash function.

Tried the command without parameters and found it pulls the templates from this repo's templates. Something I didn't expect, but it didn't overwrite changes to the existing templates, so I don't see a problem with that.

Nice work!

@ericstoekl
Copy link
Contributor Author

Work in this PR is continued here: #201

@ericstoekl ericstoekl closed this Nov 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants