github.com/mkimuram/operator-sdk@v0.7.1-0.20190410172100-52ad33a4bda0/cmd/operator-sdk/migrate/cmd.go (about)

     1  // Copyright 2019 The Operator-SDK Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package migrate
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"path/filepath"
    21  
    22  	"github.com/operator-framework/operator-sdk/internal/pkg/scaffold"
    23  	"github.com/operator-framework/operator-sdk/internal/pkg/scaffold/ansible"
    24  	"github.com/operator-framework/operator-sdk/internal/pkg/scaffold/helm"
    25  	"github.com/operator-framework/operator-sdk/internal/pkg/scaffold/input"
    26  	"github.com/operator-framework/operator-sdk/internal/util/projutil"
    27  
    28  	log "github.com/sirupsen/logrus"
    29  	"github.com/spf13/cobra"
    30  )
    31  
    32  // NewCmd returns a command that will add source code to an existing non-go operator
    33  func NewCmd() *cobra.Command {
    34  	return &cobra.Command{
    35  		Use:   "migrate",
    36  		Short: "Adds source code to an operator",
    37  		Long:  `operator-sdk migrate adds a main.go source file and any associated source files for an operator that is not of the "go" type.`,
    38  		RunE:  migrateRun,
    39  	}
    40  }
    41  
    42  // migrateRun determines the current operator type and runs the corresponding
    43  // migrate function.
    44  func migrateRun(cmd *cobra.Command, args []string) error {
    45  	projutil.MustInProjectRoot()
    46  
    47  	_ = projutil.CheckAndGetProjectGoPkg()
    48  
    49  	opType := projutil.GetOperatorType()
    50  	switch opType {
    51  	case projutil.OperatorTypeAnsible:
    52  		return migrateAnsible()
    53  	case projutil.OperatorTypeHelm:
    54  		return migrateHelm()
    55  	}
    56  	return fmt.Errorf("operator of type %s cannot be migrated", opType)
    57  }
    58  
    59  // migrateAnsible runs the migration process for an ansible-based operator
    60  func migrateAnsible() error {
    61  	wd := projutil.MustGetwd()
    62  
    63  	cfg := &input.Config{
    64  		AbsProjectPath: wd,
    65  		ProjectName:    filepath.Base(wd),
    66  	}
    67  
    68  	dockerfile := ansible.DockerfileHybrid{
    69  		Watches: true,
    70  		Roles:   true,
    71  	}
    72  	_, err := os.Stat(ansible.PlaybookYamlFile)
    73  	switch {
    74  	case err == nil:
    75  		dockerfile.Playbook = true
    76  	case os.IsNotExist(err):
    77  		log.Info("No playbook was found, so not including it in the new Dockerfile")
    78  	default:
    79  		return fmt.Errorf("error trying to stat %s: (%v)", ansible.PlaybookYamlFile, err)
    80  	}
    81  
    82  	if err := renameDockerfile(); err != nil {
    83  		return err
    84  	}
    85  
    86  	s := &scaffold.Scaffold{}
    87  	err = s.Execute(cfg,
    88  		&ansible.Main{},
    89  		&ansible.GopkgToml{},
    90  		&dockerfile,
    91  		&ansible.Entrypoint{},
    92  		&ansible.UserSetup{},
    93  		&ansible.K8sStatus{},
    94  		&ansible.AoLogs{},
    95  	)
    96  	if err != nil {
    97  		return fmt.Errorf("migrate ansible scaffold failed: (%v)", err)
    98  	}
    99  	return nil
   100  }
   101  
   102  // migrateHelm runs the migration process for a helm-based operator
   103  func migrateHelm() error {
   104  	wd := projutil.MustGetwd()
   105  
   106  	cfg := &input.Config{
   107  		AbsProjectPath: wd,
   108  		ProjectName:    filepath.Base(wd),
   109  	}
   110  
   111  	if err := renameDockerfile(); err != nil {
   112  		return err
   113  	}
   114  
   115  	s := &scaffold.Scaffold{}
   116  	err := s.Execute(cfg,
   117  		&helm.Main{},
   118  		&helm.GopkgToml{},
   119  		&helm.DockerfileHybrid{
   120  			Watches:    true,
   121  			HelmCharts: true,
   122  		},
   123  		&helm.Entrypoint{},
   124  		&helm.UserSetup{},
   125  	)
   126  	if err != nil {
   127  		return fmt.Errorf("migrate helm scaffold failed: (%v)", err)
   128  	}
   129  	return nil
   130  }
   131  
   132  func renameDockerfile() error {
   133  	dockerfilePath := filepath.Join(scaffold.BuildDir, scaffold.DockerfileFile)
   134  	newDockerfilePath := dockerfilePath + ".sdkold"
   135  	err := os.Rename(dockerfilePath, newDockerfilePath)
   136  	if err != nil {
   137  		return fmt.Errorf("failed to rename Dockerfile: (%v)", err)
   138  	}
   139  	log.Infof("Renamed Dockerfile to %s and replaced with newer version. Compare the new Dockerfile to your old one and manually migrate any customizations", newDockerfilePath)
   140  	return nil
   141  }