示例#1
0
func GenerateFullUpdate(version string, prod bool) error {
	var variant string
	if prod {
		variant = "production"
	} else {
		variant = "developer"
	}

	var (
		dir           = sdk.BuildImageDir(version)
		update_prefix = filepath.Join(dir, "coreos_"+variant+"_update")
		update_bin    = update_prefix + ".bin"
		update_gz     = update_prefix + ".gz"
		update_xml    = update_prefix + ".xml"
	)

	if err := checkUpdate(dir, update_xml); err == nil {
		plog.Infof("Using update manifest: %s", update_xml)
		return nil
	}

	plog.Noticef("Generating update payload: %s", update_gz)
	if err := run("delta_generator",
		"-new_image", update_bin,
		"-out_file", update_gz,
		"-private_key", privateKey); err != nil {
		return err
	}

	plog.Infof("Writing update manifest: %s", update_xml)
	update := omaha.Update{Id: sdk.GetDefaultAppId()}
	pkg, err := update.AddPackageFromPath(update_gz)

	// update engine needs the payload hash here in the action element
	postinstall := update.AddAction("postinstall")
	postinstall.Sha256 = pkg.Sha256

	update.Version, err = sdk.GetVersionFromDir(dir)
	if err != nil {
		return err
	}

	return xmlMarshalFile(update_xml, &update)
}
示例#2
0
func runUpdatePayload(cmd *cobra.Command, args []string) {
	if len(args) != 0 {
		plog.Fatal("No args accepted")
	}

	plog.Info("Generating update payload")

	// check for update file, generate if it doesn't exist
	version := "latest"
	dir := sdk.BuildImageDir(version)
	payload := "coreos_production_update.gz"

	_, err := os.Stat(filepath.Join(dir, payload))
	if err != nil {
		err = sdkomaha.GenerateFullUpdate("latest", true)
		if err != nil {
			plog.Fatalf("Building full update failed: %v", err)
		}
	}

	plog.Info("Bringing up test harness cluster")

	cluster, err := platform.NewQemuCluster(kola.QEMUOptions)
	qc := cluster.(*platform.QEMUCluster)
	if err != nil {
		plog.Fatalf("Cluster failed: %v", err)
	}
	defer cluster.Destroy()

	svc := &updateServer{
		updatePath: dir,
		payload:    payload,
	}

	qc.OmahaServer.Updater = svc

	// tell omaha server to handle file requests for the images dir
	qc.OmahaServer.Mux.Handle(dir+"/", http.StripPrefix(dir+"/", http.FileServer(http.Dir(dir))))

	_, port, err := net.SplitHostPort(qc.OmahaServer.Addr().String())
	if err != nil {
		plog.Errorf("SplitHostPort failed: %v", err)
		return
	}

	tmplVals := map[string]string{
		"Server": fmt.Sprintf("10.0.0.1:%s", port),
	}

	tmpl := template.Must(template.New("userdata").Parse(userdata))
	buf := new(bytes.Buffer)

	err = tmpl.Execute(buf, tmplVals)
	if err != nil {
		plog.Errorf("Template execution failed: %v", err)
		return
	}

	plog.Infof("Spawning test machine")

	m, err := cluster.NewMachine(buf.String())
	if err != nil {
		plog.Errorf("Machine failed: %v", err)
		return
	}

	plog.Info("Checking for boot from USR-A partition")

	/* check that we are on USR-A. */
	if err := checkUsrPartition(m, []string{"PARTUUID=" + sdk.USRAUUID.String(), "PARTLABEL=USR-A"}); err != nil {
		plog.Errorf("Did not find USR-A partition: %v", err)
		return
	}

	plog.Infof("Triggering update_engine")

	/* trigger update, monitor the progress. */
	out, err := m.SSH("update_engine_client -check_for_update")
	if err != nil {
		plog.Errorf("Executing update_engine_client failed: %v: %v", out, err)
		return
	}

	checker := func() error {
		envs, err := m.SSH("update_engine_client -status 2>/dev/null")
		if err != nil {
			return err
		}

		em := splitNewlineEnv(string(envs))

		if em["CURRENT_OP"] != "UPDATE_STATUS_UPDATED_NEED_REBOOT" {
			return fmt.Errorf("have not arrived in reboot state: currently at %s", em["CURRENT_OP"])
		}

		return nil
	}

	if err := util.Retry(12, 10*time.Second, checker); err != nil {
		plog.Errorf("Applying update payload failed: %v", err)
		return
	}

	plog.Info("Rebooting test machine")

	/* reboot it */
	if err := platform.Reboot(m); err != nil {
		plog.Errorf("Rebooting machine failed: %v", err)
		return
	}

	plog.Info("Checking for boot from USR-B partition")

	/* check that we are on USR-B now. */
	if err := checkUsrPartition(m, []string{"PARTUUID=" + sdk.USRBUUID.String(), "PARTLABEL=USR-B"}); err != nil {
		plog.Errorf("Did not find USR-B partition: %v", err)
		return
	}

	plog.Info("Update complete!")
}