2 Copyright 2019 The ELIOT Team .
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
29 "github.com/spf13/pflag"
30 types "elcli/cmd/common"
33 //Constants used by installers
35 UbuntuOSType = "ubuntu"
38 DefaultDownloadURL = "https://download.docker.com"
39 DockerPreqReqList = "apt-transport-https ca-certificates curl gnupg-agent software-properties-common"
41 KubernetesDownloadURL = "https://apt.kubernetes.io/"
42 KubernetesGPGURL = "https://packages.cloud.google.com/apt/doc/apt-key.gpg"
44 KubeAPIServerName = "kube-apiserver"
47 //AddToolVals gets the value and default values of each flags and collects them in temporary cache
48 func AddToolVals(f *pflag.Flag, flagData map[string]types.FlagData) {
49 flagData[f.Name] = types.FlagData{Val: f.Value.String(), DefVal: f.DefValue}
52 //CheckIfAvailable checks is val of a flag is empty then return the default value
53 func CheckIfAvailable(val, defval string) string {
60 //Common struct contains OS and Tool version properties and also embeds OS interface
68 //SetOSInterface defines a method to set the implemtation of the OS interface
69 func (co *Common) SetOSInterface(intf types.OSTypeInstaller) {
70 co.OSTypeInstaller = intf
73 //Command defines commands to be executed and captures std out and std error
80 //ExecuteCommand executes the command and captures the output in stdOut
81 func (cm *Command) ExecuteCommand() {
83 cm.StdOut, err = cm.Cmd.Output()
85 fmt.Println("Output failed: ", err)
86 cm.StdErr = []byte(err.Error())
90 //GetStdOutput gets StdOut field
91 func (cm Command) GetStdOutput() string {
92 if len(cm.StdOut) != 0 {
93 return strings.TrimRight(string(cm.StdOut), "\n")
98 //GetStdErr gets StdErr field
99 func (cm Command) GetStdErr() string {
100 if len(cm.StdErr) != 0 {
101 return strings.TrimRight(string(cm.StdErr), "\n")
106 //ExecuteCmdShowOutput captures both StdOut and StdErr after exec.cmd().
107 //It helps in the commands where it takes some time for execution.
108 func (cm Command) ExecuteCmdShowOutput() error {
109 var stdoutBuf, stderrBuf bytes.Buffer
110 stdoutIn, _ := cm.Cmd.StdoutPipe()
111 stderrIn, _ := cm.Cmd.StderrPipe()
113 var errStdout, errStderr error
114 stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
115 stderr := io.MultiWriter(os.Stderr, &stderrBuf)
116 err := cm.Cmd.Start()
118 return fmt.Errorf("failed to start '%s' because of error : %s", strings.Join(cm.Cmd.Args, " "), err.Error())
121 var wg sync.WaitGroup
125 _, errStdout = io.Copy(stdout, stdoutIn)
129 _, errStderr = io.Copy(stderr, stderrIn)
134 return fmt.Errorf("failed to run '%s' because of error : %s", strings.Join(cm.Cmd.Args, " "), err.Error())
136 if errStdout != nil || errStderr != nil {
137 return fmt.Errorf("failed to capture stdout or stderr")
140 cm.StdOut, cm.StdErr = stdoutBuf.Bytes(), stderrBuf.Bytes()
144 //GetOSVersion gets the OS name
145 func GetOSVersion() string {
146 c := &Command{Cmd: exec.Command("sh", "-c", ". /etc/os-release && echo $ID")}
148 return c.GetStdOutput()
151 //GetOSInterface helps in returning OS specific object which implements OSTypeInstaller interface.
152 func GetOSInterface() types.OSTypeInstaller {
154 switch GetOSVersion() {
160 panic("This OS version is currently un-supported by keadm")
164 // IsCloudCore identifies if the node is having cloudcore and kube-apiserver already running.
165 // If so, then return true, else it can used as edge node and initialise it.
166 func IsCloudCore() (types.ModuleRunning, error) {
167 //osType := GetOSInterface()
169 //If any of cloudcore or K8S API server is running, then we believe the node is cloud node
171 return types.NoneRunning, nil
174 //IsK8SClusterRunning check whether Kubernetes Master is running already on the server in which ELIOT Setup command is executed
175 //Currently there is no check on the ELIOT Edge Nodes.
176 func IsK8SClusterRunning() (bool, error) {
177 shK8SClusterRunning := fmt.Sprintf("ps aux | grep kube- | grep -v grep | wc -l")
178 cmd := &Command {Cmd : exec.Command ("sh" , "-c" ,shK8SClusterRunning)}
180 stdOut:= cmd.GetStdOutput()
181 errOut:= cmd.GetStdErr()
184 return false, fmt.Errorf("%s", errOut)
193 // runCommandWithShell executes the given command with "sh -c".
194 // It returns an error if the command outputs anything on the stderr.
195 func runCommandWithShell(command string) (string, error) {
196 cmd := &Command{Cmd: exec.Command("sh", "-c", command)}
197 err := cmd.ExecuteCmdShowOutput()
201 errout := cmd.GetStdErr()
203 return "", fmt.Errorf("%s", errout)
205 return cmd.GetStdOutput(), nil